我正在运行一个模拟程序,其中需要生成许多随机数。随机数发生器是作为C++对象实现的,该对象具有返回随机数的公共方法。为了与OpenMP并行化一起使用,我只需创建一个包含多个RNG对象的数组,每个线程都有一个RNG对象。然后每个线程通过调用其中一个RNG对象来生成自己的随机数。例如:
for (int i = 0; i < iTotThreads; i++) {
aRNG[i] = new RNG();
}
// ... stuff here
#pragma omp parallel
{
iT = omp_get_thread_num();
#pragma omp for
for ( /* big loop */) {
// more stuff
aRNG[iT]->getRandomNumber();
// more stuff
}
}
尽管每个随机数生成器(RNG)都在其自己的成员变量上工作,并且两个这样的RNG不适合单个缓存行(我还尝试在创建时明确对齐它们的每个变量),但似乎存在一些错误共享,因为代码根本不具有可扩展性。
如果我在omp并行区域内实例化对象:
#pragma omp parallel
{
i = omp_get_thread_num();
aRNG[i] = new RNG();
}
代码可以完美地扩展。你有任何想法吗?
编辑:顺便说一下,在第二种情况(可以很好地扩展),我创建RNG的并行区域与我使用它们的并行区域不同。我指望当我进入第二个并行区域时,aRNG[]
中的每个指针仍然指向我的对象之一,但我想这是不好的实践...