我试图与OpenMP并行化for循环 . 通常这应该是相当简单的 . 但是,我需要在执行for循环之前执行特定于线程的初始化 .
具体来说,我有以下问题:我有一个不是线程安全的随机数生成器,所以我需要为每个线程创建一个RNG实例 . 但我想确保不是每个线程都会产生相同的随机数 .
所以我尝试了以下方法:
#pragma omp parallel
{
int rndseed = 42;
#ifdef _OPENMP
rndseed += omp_get_thread_num();
#endif
// initialize randon number generator
#pragma omp for
for (int sampleid = 0; sampleid < numsamples; ++sampleid)
{
// do stuff
}
}
如果我使用此构造,我在运行时收到以下错误消息:
致命用户错误1002:'#pragma omp for'不正确地嵌套在工作共享构造中
那么有没有办法进行特定于线程的初始化?
谢谢
2 回答
你有错误:
是指工作共享结构的非法嵌套 . 事实上,OpenMP 3.1标准在第2.5节中给出了以下限制:
从上面引用的行可以看出,在同一个并行区域内嵌套不同的工作共享构造是不一致的 .
尽管在您的代码段中看不到非法嵌套,但我认为它隐藏了相对于实际代码的帖子过于简单化 . 只是为了给你一个提示,最常见的情况是:
嵌套在单个构造中的
循环工作共享构造(类似示例here)
循环工作共享构造嵌套在另一个循环结构中
如果您有兴趣,请在this answer中详细讨论后一种情况 .
我认为存在设计错误 .
并行for循环不仅仅是N个线程,例如N个核心数,但可能是N * X个线程,1 <= N * X <numsamples .
如果你想要一个“迭代私有”变量,那么就在loop-body中声明它(但你已经知道了);但声明在并行for循环中使用的线程私有变量可能不够合理 .