diff --git a/dn2/Makefile b/dn2/Makefile index 3ff03d1..530e632 100644 --- a/dn2/Makefile +++ b/dn2/Makefile @@ -1,5 +1,5 @@ CC=gcc -CFLAGS=-g -Wall -lpthread +CFLAGS=-g -Wall -lpthread -fopenmp all: server diff --git a/dn2/server b/dn2/server index 99371ff..b07383f 100755 Binary files a/dn2/server and b/dn2/server differ diff --git a/dn2/server.c b/dn2/server.c index dbe7818..9ff2834 100644 --- a/dn2/server.c +++ b/dn2/server.c @@ -1,17 +1,20 @@ #include #include +#include +#include +#include #define N_THREADS 1 -#define N_STEPS 1 -#define N_NUMBERS_CALCULATED 2000 +#define N_STEPS 200 +#define N_NUMBERS_CALCULATED 100000 -typedef struct _IntervalInfo { - int start; - int end; -} IntervalInfo; +pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +pthread_spinlock_t alive_threads_lock; +pthread_spinlock_t produced_numbers_lock; -int friendly_numbers[N_NUMBERS_CALCULATED]; +int amicable_numbers[N_NUMBERS_CALCULATED]; long produced = 0; +int threads_alive = 0; int calculate_amicable_number(int number) { for(int i=1; i< number; i++){ @@ -23,15 +26,65 @@ int calculate_amicable_number(int number) { } void *calculate_amicable_number_invterval(void * arg) { + int *myrank = (int *)arg; + long mystart = (int)(N_NUMBERS_CALCULATED/ (double)N_THREADS * *myrank); + long myend = (int)(N_NUMBERS_CALCULATED / (double)N_THREADS * (*myrank + 1)); + + for(int i = mystart; i < myend; i++) { + amicable_numbers[i] = calculate_amicable_number(i); + } + return NULL; } +int not_all_numbers_calculated() { + int ret = 0; + pthread_spin_lock(&produced_numbers_lock); + if(produced < N_NUMBERS_CALCULATED) + ret = 1; + pthread_spin_unlock(&produced_numbers_lock); + return ret; +} + +int is_there_space_for_new_thread() { + int ret = 0; + pthread_spin_lock(&alive_threads_lock); + if (threads_alive < N_THREADS) + ret = 1; + pthread_spin_unlock(&alive_threads_lock); + return ret; +} + int main() { - pthread_t threads[N_NUMBERS_CALCULATED]; + pthread_spin_init(&alive_threads_lock, PTHREAD_PROCESS_PRIVATE); + pthread_spin_init(&produced_numbers_lock, PTHREAD_PROCESS_PRIVATE); + pthread_t t[N_THREADS]; + int p[N_THREADS]; + + double dt = omp_get_wtime(); + + for (int i = 0; i +#include +#include +#include +#include + +#define N_THREADS 5 +#define N_STEPS 200 +#define N_NUMBERS_CALCULATED 10000 + +pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +pthread_spinlock_t alive_threads_lock; +pthread_spinlock_t produced_numbers_lock; + +int amicable_numbers[N_NUMBERS_CALCULATED]; +long produced = 0; +int threads_alive = 0; + +int calculate_amicable_number(int number) { + for(int i=1; i< number; i++){ + if(number % i == 0){ + number = number + i; + } + } + return number; +} + +void *calculate_amicable_number_invterval(void * arg) { + int start = *((int *)arg); + int calculated = 0; + int h = 0; + + for(int i = 0; i < N_STEPS; i++){ + calculated = calculate_amicable_number(start + i); + h++; + if (start + i < N_NUMBERS_CALCULATED) { + amicable_numbers[start +i] = calculated; + } else { + pthread_spin_lock(&alive_threads_lock); + threads_alive--; + printf("My thread start was: %d and I calculated %d numbers\n", start, h); + pthread_spin_unlock(&alive_threads_lock); + free(arg); + return NULL; + } + } + + pthread_spin_lock(&alive_threads_lock); + threads_alive--; + pthread_spin_unlock(&alive_threads_lock); + printf("my thread start was: %d and i calculated %d numbers\n", start, h); + free(arg); + return NULL; +} + +int not_all_numbers_calculated() { + int ret = 0; + pthread_spin_lock(&produced_numbers_lock); + if(produced < N_NUMBERS_CALCULATED) + ret = 1; + pthread_spin_unlock(&produced_numbers_lock); + return ret; +} + +int is_there_space_for_new_thread() { + int ret = 0; + pthread_spin_lock(&alive_threads_lock); + if (threads_alive < N_THREADS) + ret = 1; + pthread_spin_unlock(&alive_threads_lock); + return ret; +} + +int main() { + pthread_spin_init(&alive_threads_lock, PTHREAD_PROCESS_PRIVATE); + pthread_spin_init(&produced_numbers_lock, PTHREAD_PROCESS_PRIVATE); + + pthread_t thread; + double dt = omp_get_wtime(); + + while(not_all_numbers_calculated()){ + + if(is_there_space_for_new_thread()) { + int *arg = malloc(sizeof(*arg)); + pthread_spin_lock(&produced_numbers_lock); + *arg = produced; + pthread_spin_unlock(&produced_numbers_lock); + pthread_create(&thread, NULL, calculate_amicable_number_invterval,(void *) arg); + pthread_spin_lock(&alive_threads_lock); + threads_alive += 1; + pthread_spin_unlock(&alive_threads_lock); + pthread_spin_lock(&produced_numbers_lock); + produced += N_STEPS; + pthread_spin_unlock(&produced_numbers_lock); + } + } + dt = omp_get_wtime() - dt; + + sleep(1); + printf("Sleeping 2 seconds, waiting for all threads to finish\n"); + for(int i = 0; i < N_NUMBERS_CALCULATED; i++){ + printf("%d, ", amicable_numbers[i]); + } + + printf("\nExecution time: %lf\n", dt); + return 0; + + /// 10 000 korakov + /// 1 THREAD: 27.789431 + /// 2 THREADS: 11.234548 + /// 4 THREADS: 4.232311 + /// 8 THREADS: 1.551455 + /// 16 THREADS: 0.605447 + +}