0

我正在尝试使用 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”未正确嵌套在工作共享结构中

那么有没有办法进行线程特定的初始化?

谢谢

4

2 回答 2

0

我认为存在设计错误。

例如,并行 for 循环不仅仅是 N 个线程和 N 个内核数,而且可能是 N*X 个线程,其中 1 <= N*X < numsamples。

如果你想要一个“迭代私有”变量,那么就在循环体中声明它(但你已经知道了);但是声明一个线程私有变量以在并行 for 循环中使用可能不够合理。

于 2013-06-17T10:45:58.890 回答
0

您遇到的错误:

Fatal User Error 1002: '#pragma omp for' improperly nested in a work-sharing construct

工作共享结构的非法嵌套。事实上,OpenMP 3.1 标准在 2.5 节中给出了以下限制:

  • 团队中的所有线程都必须遇到每个工作共享区域,或者根本不遇到。
  • 对于团队中的每个线程,遇到的工作共享区域和屏障区域的顺序必须相同。

从上面引用的行可以看出,在同一并行区域内嵌套不同的工作共享结构是不符合的。

尽管非法嵌套在您的代码段中不可见,但我认为它是由于帖子相对于实际代码的过度简化而隐藏的。只是给你一个提示,最常见的情况是:

  • 嵌套在单个构造中的循环工作共享构造(类似于此处的示例)
  • 嵌套在另一个循环构造中的循环工作共享构造

如果您有兴趣,在此答案中将更详细地讨论后一种情况。

于 2013-06-17T19:14:06.827 回答