diff --git a/threads/atomic/Makefile b/threads/atomic/Makefile new file mode 100644 index 0000000..1f5c123 --- /dev/null +++ b/threads/atomic/Makefile @@ -0,0 +1,4 @@ +test : atomics.c + gcc atomics.c -o atomics +clean: + rm atomics diff --git a/threads/README.md b/threads/atomic/README.md similarity index 100% rename from threads/README.md rename to threads/atomic/README.md diff --git a/threads/atomic/atomics.c b/threads/atomic/atomics.c new file mode 100644 index 0000000..38c9596 --- /dev/null +++ b/threads/atomic/atomics.c @@ -0,0 +1,164 @@ +/* + * measures the performance cost by time of using locks in multi-thread program + * Measure the overhead of calling lock and unlock depending on the level of contention + * by utilizing clock(), in time.h + * Author: Wenhui Zhang, Hu Yang, Pradeep + */ + + + +#include +#include +#include +#include + + + +int ctr; +pthread_mutex_t count_mutex; +clock_t start_t, end_t; + + + + +/* thread_lock: thread function for multi-thread generation */ +void thread_lock() +{ + + for ( int i = 0; i < 10000; i++){ + pthread_mutex_lock(&count_mutex); + + ctr = ctr + 1; + //printf("%d \n", ctr); + + pthread_mutex_unlock(&count_mutex); + } +} + + +/* thread_atomic: thread function for multi-thread generation */ +void thread_atomic() +{ + + for ( int i = 0; i < 10000; i++){ + __sync_add_and_fetch(&ctr, 1); + //printf("%d \n", ctr); + } + +} + + +/* compare_and_swap: thread function for multi-thread generation */ +/* + void compare_and_swap() + { + + pthread_mutex_lock(&count_mutex); + + int oldvalue = 3; + int newvalue = 4; + int *ptr = &newvalue; + int temp = *ptr; + if(*ptr == oldvalue) + *ptr = newvalue; + + pthread_mutex_unlock(&count_mutex); + + } + */ + + + + +int atomic_comp(int num_threads) +{ + + + printf("Start of %d thread calculating...\n", num_threads); + double total_t_lock, total_t_unlock; //time counter + int rc; + int tnum; //counter for threads + pthread_mutex_init(&count_mutex, NULL); //initialize mutex + + + pthread_t thread_info[num_threads]; // thread identifier + + /* Test for thread_incr_lock */ + + + start_t = clock(); + for (tnum = 0; tnum < num_threads; tnum++){ + //printf("create thread %d\n", tnum); + + rc = pthread_create(&thread_info[tnum], NULL, (void*)&thread_lock, NULL); + if (rc){ + printf("ERROR; return code from pthread_create() is %d\n", rc); + exit(1); + } + } + + + for (tnum = 0; tnum < num_threads; tnum++){ + pthread_join(thread_info[tnum], NULL); + } + + + end_t = clock(); + + total_t_lock = (double)((end_t - start_t) / (double)CLOCKS_PER_SEC); + printf("Total time cost by running %d threads for increase function with lock implementation: %f\n sec", num_threads, total_t_lock); + + + + /* Test for thread_atomic */ + + ctr = 0; + + + start_t = clock(); + for (tnum = 0; tnum < num_threads; tnum++){ + //printf("create thread %d\n", tnum); + + rc = pthread_create(&thread_info[tnum], NULL, (void*)&thread_atomic, NULL); + if (rc){ + printf("ERROR; return code from pthread_create() is %d\n", rc); + exit(1); + } + } + + + for (tnum = 0; tnum < num_threads; tnum++){ + pthread_join(thread_info[tnum], NULL); + } + + end_t = clock(); + + total_t_unlock = (double)( (end_t - start_t) / (double)CLOCKS_PER_SEC); + printf("Total time cost by running %d threads for increase function with atomic: %f sec\n", num_threads, total_t_unlock); + + + + printf("Mutex Time Cost Against Atomic by running %d threads for increase function: %f sec\n", num_threads, total_t_lock - total_t_unlock); + + + printf("Per thread Mutex Time Cost Against Atomic by running %d threads for increase function: %f sec\n", num_threads, (total_t_lock - total_t_unlock)/(double)num_threads); + + printf("End of %d thread calculating...\n", num_threads); + + return 0; +} + + + +int main(void) +{ + printf("------------------------\n"); + atomic_comp(16); + printf("------------------------\n"); + atomic_comp(1); + printf("------------------------\n"); + atomic_comp(160); + + return 0; + +} diff --git a/threads/atomic/output_atomics b/threads/atomic/output_atomics new file mode 100644 index 0000000..4042f99 --- /dev/null +++ b/threads/atomic/output_atomics @@ -0,0 +1,22 @@ +wenhui-2:threads WenhuiZhang$ ./atomics +------------------------ +Start of 16 thread calculating... +Total time cost by running 16 threads for increase function with lock implementation: 0.680011 + secTotal time cost by running 16 threads for increase function with atomic: 0.016044 sec +Mutex Time Cost Against Atomic by running 16 threads for increase function: 0.663967 sec +Per thread Mutex Time Cost Against Atomic by running 16 threads for increase function: 0.041498 sec +End of 16 thread calculating... +------------------------ +Start of 1 thread calculating... +Total time cost by running 1 threads for increase function with lock implementation: 0.000611 + secTotal time cost by running 1 threads for increase function with atomic: 0.000132 sec +Mutex Time Cost Against Atomic by running 1 threads for increase function: 0.000479 sec +Per thread Mutex Time Cost Against Atomic by running 1 threads for increase function: 0.000479 sec +End of 1 thread calculating... +------------------------ +Start of 160 thread calculating... +Total time cost by running 160 threads for increase function with lock implementation: 7.917729 + secTotal time cost by running 160 threads for increase function with atomic: 0.159848 sec +Mutex Time Cost Against Atomic by running 160 threads for increase function: 7.757881 sec +Per thread Mutex Time Cost Against Atomic by running 160 threads for increase function: 0.048487 sec +End of 160 thread calculating...