Reputation: 783
I am trying to understand the atomic operations, and I have prepared the sample code below. But I am getting the same result - 150 - when I define one of these conditional compilation flags - MUTEX, ATOMIC and NONE.
How can I verify inter-threaded arithmetic operations are working properly?
My pc is "2.6.35-30-generic #61-Ubuntu SMP x86_64 GNU/Linux" and it has 4 cores.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h>
#include <sys/types.h>
#define THREAD_NUM 10
#define INC_NUM 15
//#define MUTEX
#define ATOMIC
//#define NONE
volatile int g_counter = 0;
void *thread_func(void *ptr);
pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER;
int main(int argc ,char **argv) {
pthread_t thread[THREAD_NUM];
int iret[THREAD_NUM];
int nt;
for (nt = 0; nt<THREAD_NUM; nt++)
iret[nt] = pthread_create( &thread[nt], NULL, thread_func, NULL);
for (nt = 0; nt<THREAD_NUM; nt++)
pthread_join(thread[nt], NULL);
printf("counter val = %d\n", g_counter);
return 0;
}
void *thread_func(void *ptr) {
int cnt;
for (cnt = 0; cnt<INC_NUM; cnt++) {
#ifdef MUTEX
pthread_mutex_lock( &thread_mutex );
g_counter++;
pthread_mutex_unlock(&thread_mutex);
#endif
#ifdef ATOMIC
__sync_fetch_and_add(&g_counter, 1);
#endif
#ifdef NONE
g_counter++;
#endif
}
return NULL;
}
Upvotes: 0
Views: 585
Reputation: 3221
When I ran your code with INC_NUM of 100000, I got significantly differing values -- with NONE defined, the sum was never the correct value of 1000000. Your INC_NUM value is too small.
There was no difference between MUTEX and ATOMIC, (nor should there be, of course), although I assume there will be performance differences.
You might find it informative to modify your code to show the order in which threads start and finish, as below:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h>
#include <sys/types.h>
#define THREAD_NUM 10
#define INC_NUM 100000
//#define MUTEX
// #define ATOMIC
#define NONE
volatile int g_counter = 0;
void *thread_func(void *ptr);
pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER;
int main(int argc ,char **argv) {
pthread_t thread[THREAD_NUM];
int iret[THREAD_NUM];
int nt;
for (nt = 0; nt<THREAD_NUM; nt++)
iret[nt] = pthread_create( &thread[nt], NULL, thread_func, (void *)nt);
for (nt = 0; nt<THREAD_NUM; nt++)
pthread_join(thread[nt], NULL);
printf("counter val = %d\n", g_counter);
return 0;
}
void *thread_func(void *ptr) {
int cnt;
printf("Thread %d started.\n", (int)ptr);
for (cnt = 0; cnt<INC_NUM; cnt++) {
#ifdef MUTEX
pthread_mutex_lock( &thread_mutex );
g_counter++;
pthread_mutex_unlock(&thread_mutex);
#endif
#ifdef ATOMIC
__sync_fetch_and_add(&g_counter, 1);
#endif
#ifdef NONE
g_counter++;
#endif
}
printf("Thread %d finished.\n", (int)ptr);
return NULL;
}
Upvotes: 4