Я опубликую здесь то, что я отправил Параллельное генерирование случайных чисел :
Я думаю, что вы ищете rand_r (), который явно принимает текущее состояние ГСЧ в качестве параметра. Тогда каждый поток должен иметь свою собственную копию начальных данных (хотите ли вы, чтобы каждый поток начинался с одного и того же начального или другого, зависит от того, что вы делаете, здесь вы хотите, чтобы они были разными, или вы получите ту же строку опять и опять). Здесь обсуждается rand_r () и безопасность потоков: действительно ли rand_r безопасен для потоков? .
Допустим, вы хотели, чтобы у каждого потока было начальное начальное число с номера потока (что, вероятно, не то, что вам нужно, так как он будет давать одинаковые результаты при каждом запуске с одинаковым числом потоков, но просто как пример):
#pragma omp parallel default(none)
{
int i;
unsigned int myseed = omp_get_thread_num();
#pragma omp for
for(i=0; i<100; i++)
printf("%d %d %d\n",i,omp_get_thread_num(),rand_r(&myseed));
}
Редактировать : Просто на жаворонке проверил, не ускорится ли вышеописанное. Полный код был
#define NRANDS 1000000
int main(int argc, char **argv) {
struct timeval t;
int a[NRANDS];
tick(&t);
#pragma omp parallel default(none) shared(a)
{
int i;
unsigned int myseed = omp_get_thread_num();
#pragma omp for
for(i=0; i<NRANDS; i++)
a[i] = rand_r(&myseed);
}
double sum = 0.;
double time=tock(&t);
for (long int i=0; i<NRANDS; i++) {
sum += a[i];
}
printf("Time = %lf, sum = %lf\n", time, sum);
return 0;
}
, где tick и tock - это просто оболочки для gettimeofday()
, а tock () возвращает разницу в секундах. Сумма печатается только для того, чтобы убедиться, что ничего не оптимизировано, и для демонстрации небольшой точки; вы получите разные числа с разными номерами потоков, потому что каждый поток получает свой собственный номер потока в качестве начального числа; если вы снова и снова запускаете один и тот же код с одним и тем же количеством потоков, вы получите одну и ту же сумму по той же причине. В любом случае, время (работающее на 8-ядерном Nehalem Box без других пользователей):
$ export OMP_NUM_THREADS=1
$ ./rand
Time = 0.008639, sum = 1074808568711883.000000
$ export OMP_NUM_THREADS=2
$ ./rand
Time = 0.006274, sum = 1074093295878604.000000
$ export OMP_NUM_THREADS=4
$ ./rand
Time = 0.005335, sum = 1073422298606608.000000
$ export OMP_NUM_THREADS=8
$ ./rand
Time = 0.004163, sum = 1073971133482410.000000
Так что ускорение, если не большое; как указывает @ruslik, это не очень сложный процесс, и другие проблемы, такие как пропускная способность памяти, начинают играть свою роль. Таким образом, только 8-кратное ускорение на 8 ядер.