# Four threads runs 4x as fast on a machine with 4 cores
$ time ./thread_sum 4 10000000000
Creating 4 threads to sum the first 10000000000 integers
Each thread will sum 2500000000 integers
Thread summing integers 2500000000 to 5000000000 finished sum is 9374999997502005248
Thread summing integers 7500000000 to 10000000000 finished sum is 21874999997502087168
Thread summing integers 5000000000 to 7500000000 finished sum is 15624999997500696576
Thread summing integers 0 to 2500000000 finished sum is 3124999997567081472
Combined sum of integers 0 to 10000000000 is 49999999990071869440
real 0m3.154s
user 0m12.563s
sys 0m0.004s
$
Note result is inexact because we use values can't be exactly represented as double
and exact value printed depends on how many threads we use - becayse we break up
the computation differently depending on number of threads
*/
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <assert.h>
struct job {
long start;
long finish;
double sum;
};
void *run_thread(void *argument) {
struct job *j = argument;
long start = j->start;
long finish = j->finish;
double sum = 0;
for (long i = start; i < finish; i++) {
sum += i;
}
j->sum = sum;
printf("Thread summing integers %10lu to %11lu finished sum is %20.0f\n", start, finish, sum);
return NULL;
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <n-threads> <n-integers-to-sum>\n", argv[0]);
return 1;
}
int n_threads = strtol(argv[1], NULL, 0);
assert(n_threads > 0 && n_threads < 1000);
long integers_to_sum = strtol(argv[2], NULL, 0);
assert(integers_to_sum > 0);
long integers_per_thread = (integers_to_sum - 1)/n_threads + 1;
printf("Creating %d threads to sum the first %lu integers\n",
n_threads, integers_to_sum);
printf("Each thread will sum %lu integers\n", integers_per_thread);
pthread_t thread_id[n_threads];
struct job jobs[n_threads];
for (int i = 0; i < n_threads; i++) {
jobs[i].start = i * integers_per_thread;
jobs[i].finish = jobs[i].start + integers_per_thread;
if (jobs[i].finish > integers_to_sum) {
jobs[i].finish = integers_to_sum;
}
// create a thread which will sum integers_per_thread integers
pthread_create(&thread_id[i], NULL, run_thread, &jobs[i]);
}
// wait for each threads to finish
// then add its individual sum to the overall sum
double overall_sum = 0;
for (int i = 0; i < n_threads;i++) {
pthread_join(thread_id[i], NULL);
overall_sum += jobs[i].sum;
}
//
printf("\nCombined sum of integers 0 to %lu is %.0f\n",
integers_to_sum, overall_sum);
return 0;
}