Question

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;
}
Was it helpful?

Solution

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;
}

OTHER TIPS

The loop needs to be larger than 150! try 1,000,000.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top