Skip to content

Instantly share code, notes, and snippets.

@szilard
Last active October 29, 2015 02:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save szilard/d3cb76839fddc2d529f3 to your computer and use it in GitHub Desktop.
Save szilard/d3cb76839fddc2d529f3 to your computer and use it in GitHub Desktop.
Parallel sum 1 bn numbers pthreads
/*
Adapted from:
https://computing.llnl.gov/tutorials/pthreads/samples/arrayloops.c
http://stackoverflow.com/questions/2962785/c-using-clock-to-measure-time-in-multi-threaded-programs
Run as:
gcc -Ofast -pthread psum.c -lm && ./a.out
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define NTHREADS 16
#define ARRAYSIZE 1000000000
#define ITERATIONS ARRAYSIZE / NTHREADS
double sum=0, *a;
pthread_mutex_t sum_mutex;
void *do_work(void *tid)
{
int i, start, *mytid, end;
double mysum=0;
mytid = (int *) tid;
start = (*mytid * ITERATIONS);
end = start + ITERATIONS;
for (i=start; i < end ; i++) {
mysum = mysum + a[i];
/* mysum = mysum + sin(a[i]); */
}
pthread_mutex_lock (&sum_mutex);
sum = sum + mysum;
pthread_mutex_unlock (&sum_mutex);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
int i, start, tids[NTHREADS];
pthread_t threads[NTHREADS];
pthread_attr_t attr;
struct timespec start_tm, finish_tm;
double elapsed;
double mysum;
a = malloc(ARRAYSIZE*sizeof(double));
for (i=0;i<ARRAYSIZE;i++){
a[i] = 1;
}
clock_gettime(CLOCK_MONOTONIC, &start_tm);
pthread_mutex_init(&sum_mutex, NULL);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for (i=0; i<NTHREADS; i++) {
tids[i] = i;
pthread_create(&threads[i], &attr, do_work, (void *) &tids[i]);
}
for (i=0; i<NTHREADS; i++) {
pthread_join(threads[i], NULL);
}
pthread_attr_destroy(&attr);
pthread_mutex_destroy(&sum_mutex);
clock_gettime(CLOCK_MONOTONIC, &finish_tm);
elapsed = (finish_tm.tv_sec - start_tm.tv_sec);
elapsed += (finish_tm.tv_nsec - start_tm.tv_nsec) / 1000000000.0;
printf ("p = %d \n", NTHREADS);
printf ("n = %e \n", (double)ARRAYSIZE);
printf ("s = %e \n", sum);
printf("time: %f\n", elapsed);
clock_gettime(CLOCK_MONOTONIC, &start_tm);
mysum = 0;
for (i=0; i < ARRAYSIZE ; i++) {
mysum = mysum + a[i];
/* mysum = mysum + sin(a[i]); */
}
clock_gettime(CLOCK_MONOTONIC, &finish_tm);
elapsed = (finish_tm.tv_sec - start_tm.tv_sec);
elapsed += (finish_tm.tv_nsec - start_tm.tv_nsec) / 1000000000.0;
printf ("s0 = %e \n", mysum);
printf("time0: %f\n", elapsed);
pthread_exit (NULL);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment