Следующая программа по существу такая же, как описанная здесь здесь. Когда я запускаю и компилирую программу, используя два потока (NTHREADS == 2), я получаю следующее время выполнения:
real 0m14.120s
user 0m25.570s
sys 0m0.050s
Когда он запускается только с одним потоком (NTHREADS == 1), я получаю время выполнения значительно лучше, хотя оно использует только одно ядро.
real 0m4.705s
user 0m4.660s
sys 0m0.010s
Моя система является двухъядерной, и я знаю, что random_r является потокобезопасным, и я уверен, что он не блокирует. Когда одна и та же программа запускается без random_r, и вычисление косинусов и синусов используется в качестве замены, двухпоточная версия работает примерно в 1/2 раза, как ожидалось.
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define NTHREADS 2
#define PRNG_BUFSZ 8
#define ITERATIONS 1000000000
void* thread_run(void* arg) {
int r1, i, totalIterations = ITERATIONS / NTHREADS;
for (i = 0; i < totalIterations; i++){
random_r((struct random_data*)arg, &r1);
}
printf("%i\n", r1);
}
int main(int argc, char** argv) {
struct random_data* rand_states = (struct random_data*)calloc(NTHREADS, sizeof(struct random_data));
char* rand_statebufs = (char*)calloc(NTHREADS, PRNG_BUFSZ);
pthread_t* thread_ids;
int t = 0;
thread_ids = (pthread_t*)calloc(NTHREADS, sizeof(pthread_t));
/* create threads */
for (t = 0; t < NTHREADS; t++) {
initstate_r(random(), &rand_statebufs[t], PRNG_BUFSZ, &rand_states[t]);
pthread_create(&thread_ids[t], NULL, &thread_run, &rand_states[t]);
}
for (t = 0; t < NTHREADS; t++) {
pthread_join(thread_ids[t], NULL);
}
free(thread_ids);
free(rand_states);
free(rand_statebufs);
}
Я смущен, почему при генерации случайных чисел две версии с резьбой работают намного хуже, чем однопоточная версия, учитывая, что random_r предназначен для использования в многопоточных приложениях.