OpenMP 'parallel for'预先初始化
OpenMP 'parallel for' with prior initialisation
我正在尝试与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'不正确嵌套在工作共享结构中
那么有一种方法来做线程特定的初始化吗?
谢谢
您的错误:
Fatal User Error 1002: '#pragma omp for' improperly nested in a work-sharing construct
指的是工作共享结构的非法嵌套。事实上,OpenMP 3.1标准在2.5节中给出了以下限制:
- 每个工作共享区域必须被团队中的所有线程遇到,或者根本没有线程遇到。
- 对于团队中的每个线程,遇到的工作共享区域和屏障区域的顺序必须相同。
从上面引用的行可以看出,在同一个并行区域内嵌套不同的工作共享结构是不一致的。
尽管非法嵌套在您的代码片段中不可见,但我认为它是由于相对于实际代码的过度简化而隐藏起来的。给你一个提示,最常见的情况是:
- 循环工作共享构造嵌套在单个构造中(类似于这里的例子)
- 循环工作共享构造嵌套在另一个循环构造
如果你感兴趣,在这个答案中,后一种情况讨论得更详细。
我认为这是一个设计错误。
一个并行的for循环不只是N个线程有N个核数,而是可能有N*X个线程,1 <= N*X <numsamples。>
如果你想要一个"迭代私有"变量,那么就在循环体中声明它(但是你已经知道了);但是声明一个线程私有变量在并行for循环中使用可能是不合理的。
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在C和C++中初始化结构中的数组
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 在函数内部的声明中初始化数组,并在外部使用它
- OpenMP 'parallel for'预先初始化