diff --git a/dn3/Makefile b/dn3/Makefile new file mode 100644 index 0000000..3cc18b1 --- /dev/null +++ b/dn3/Makefile @@ -0,0 +1,18 @@ +CC=gcc +CFLAGS=-g -Wall -lpthread -fopenmp -lm +DESTINATION=/ceph/grid/home/gs0104/dn/dn3 + +all: server + +server: server.c + $(CC) $(CFLAGS) server.c -o server + +clean: + rm server + +push: + rsync -a --progress . nsc:$(DESTINATION) + +run_remote: + ssh nsc 'cd $(DESTINATION); make clean; make server;' + ssh nsc 'srun --reservation=fri --ntasks=1 --cpus-per-task=8 --nodes=1 $(DESTINATION)/server' diff --git a/dn3/server b/dn3/server new file mode 100755 index 0000000..1824eef Binary files /dev/null and b/dn3/server differ diff --git a/dn3/server.c b/dn3/server.c new file mode 100644 index 0000000..e9ef89a --- /dev/null +++ b/dn3/server.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include +#include + +#define N_THREADS 8 +#define N_DIMENSIONS 200000000 + +pthread_barrier_t b; +long *p_s; +long *q_s; +double res[N_THREADS]; +int active_threads[N_THREADS]; + +void setup() { + p_s = (long *) malloc(N_DIMENSIONS * sizeof(long)); + q_s = (long *) malloc(N_DIMENSIONS * sizeof(long)); + for (long i = 0; i < N_DIMENSIONS; i++) { + p_s[i] = rand() % 10; + q_s[i] = rand() % 10; + } +} + +void *calculate(void* arg) { + int *myrank = (int *)arg; + long mystart = (long)(N_DIMENSIONS/ (double)N_THREADS * *myrank); + long myend = (long)(N_DIMENSIONS / (double)N_THREADS * (*myrank + 1)); + double sum = 0; + + + for (long i = mystart; i < myend; i++) { + sum += pow(p_s[i] - q_s[i], 2); + } + + res[*myrank] = sum; + printf("Thread2 %d finished\n", *myrank); + fflush(stdout); + pthread_barrier_wait( &b ); + + int n_threads = N_THREADS; + + if (n_threads != 1) { + + n_threads = N_THREADS / 2; + if (*myrank >= n_threads) { + active_threads[*myrank] = -1; + } + } + + while(1) { + if(active_threads[*myrank] != -1) { + res[*myrank] = res[*myrank * 2] + res[*myrank *2 + 1]; + } + pthread_barrier_wait( &b ); + + n_threads = n_threads / 2; + if (n_threads == 1 || n_threads == 0) { + break; + } + if (*myrank >= n_threads) { + //printf("Thread %d is on pause\n", *myrank); + active_threads[*myrank] = -1; + } + pthread_barrier_wait( &b ); + } + + return NULL; +} + + +int main() { + pthread_t t[N_THREADS]; + setup(); + double dt = omp_get_wtime(); // start timing + int p[N_THREADS]; + + if(N_THREADS %2 != 0 && N_THREADS >= 2) { + printf("Number of threads must be even!\n"); + return 1; + } + pthread_barrier_init( &b, NULL, N_THREADS ); + + for(int i = 0; i < N_THREADS; i++ ) { + p[i] = i; + pthread_create(&t[i], NULL, calculate, (void *)&p[i]); + } + + for(int i=0; i