Как проверить атомарные операции на многопоточных и многоядерных платформах в C? - PullRequest
0 голосов
/ 20 декабря 2011

Я пытаюсь понять атомарные операции, и я подготовил пример кода ниже. Но я получаю тот же результат - 150 - когда определяю один из этих флагов условной компиляции - MUTEX, ATOMIC и NONE.

Как проверить правильность работы многопоточных арифметических операций?

Мой компьютер "2.6.35-30-generic # 61-Ubuntu SMP x86_64 GNU / Linux" и имеет 4 ядра.

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

Ответы [ 2 ]

4 голосов
/ 20 декабря 2011

Когда я запустил ваш код с INC_NUM, равным 100000, я получил значительно отличающиеся значения - при заданном NONE сумма никогда не была правильной величиной 1000000. Ваше значение INC_NUM слишком мало.

Не было никакой разницы между MUTEX и ATOMIC (и, конечно, не должно быть), хотя я предполагаю, что будут различия в производительности.

Возможно, вам будет полезно изменить код, чтобы показать порядок, в котором потоки начинаются и заканчиваются, как показано ниже:

#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;
}
0 голосов
/ 05 января 2012

Цикл должен быть больше 150!попробуй 1,000,000.

...