【发布时间】:2020-05-13 17:56:56
【问题描述】:
我正在研究 C 上的 openMP 并行处理。
我做了一个简单的随机数测试器,种子值固定,用几种不同的方法测试同一个随机数序列。
这是 rng 测试器的一部分,没有使用并行处理
//1. Single thread
//set seed value
init_genrand(2020);
int fk[33] = {0};
for(int i=0;i<31250;i++){
int x = genrand_int32();
int count = 0;
for(int j=0;j<33;j++){
if(x & 1) count ++;
x = x >> 1;
}
fk[count]++;
}
int sum = 0;
for(int i=0;i<33;i++){
printf("fk[%d] = %d\n",i,fk[i]);
sum += fk[i];
}
printf("sum = %d\n",sum);
由于 rng 函数的种子值固定,此代码始终输出相同的结果。
但是,这个使用并行处理的代码没有。
//2. Multi Threads
//set seed
init_genrand(2020);
int fkMulti[33] = {0};
int count = 0;
int x = 0;
#pragma omp parallel
{
#pragma omp for private(count, x) reduction(+:fkMulti[:33])
for(int i=0;i<31250;i++)
{
count = 0;
x = genrand_int32();
for(int j=0;j<33;j++){
if(x & 1) count ++;
x = x >> 1;
}
fkMulti[count]++;
}
}
int sumMulti = 0;
for(int i=0;i<33;i++){
printf("fkMulti[%d] = %d\n",i,fkMulti[i]);
sumMulti += fkMulti[i];
}
printf("sum = %d\n",sumMulti);
它们都生成32bit随机数31250次,并通过移位运算符计算每个随机数有多少个1位。 但第二个的工作方式与第一个不同。
每次运行编译文件时结果都会发生变化。
我还检查了 Rng 函数 ( genrand_int32() ) 在这两个代码中被执行了 31250 次。
为什么即使相同的种子总是产生相同的结果,也会发生这种情况?
感谢您阅读我的问题。
【问题讨论】:
-
不得重入。
-
只是一个 WAG,但你确定种子在所有线程中都保持不变吗?尝试将调用
init_genrand移到#pragma omps 之后 -
您需要阅读并行随机数生成;您可以合理地从“并行随机数,像 1,2,3 一样简单”thesalmons.org/john/random123/papers/random123sc11.pdf 开始(然后请注意,各种数学库都实现了它们的算法......)