我在VS2008中有以下代码:

int i,j;
bool pr = false;
#pragma omp parallel for private(pr) num_threads(2)
for(i=0;i<PIC_X;i++)
{
    int rank = omp_get_thread_num();
    int count = omp_get_num_threads();
    if ( !pr )
    {
        printf_s("Hello from thread %d of %d\n", rank, count);
        pr = true;
    }
    for(j=0;j<PIC_Y;j++)
    {
        // do stuff
    }
}


(如果您想知道的话,请不要尝试创建嵌套的OpenMP循环)。问题是,num_threads子句完全无效:我只在输出中得到“来自线程1的0的问候”。我也尝试使用omp_set_num_threads(2),但无济于事。是什么赋予了?

最佳答案

您已经在并行区域之外设置了pr,然后通过将其放在private子句中将pr设置为私有。这意味着每个线程都有一个pr,但是私有pr变量未初始化。对pr使用firstprivate而不是private,以便初始化private变量。

但是,对于默认情况下循环计数器是私有的,您是错误的。 (即变量i)的工作共享(或规范)的循环计数器是私有的(OMP V2.0规范的构造第2.4.1节)。但是“ j”不是。请参阅OpenMP V2.0规范(这是Microsoft在VS2008中支持的规范)的2.7.2数据共享属性子句:


  如果在遇到并行或工作共享结构时变量可见,并且
  未在共享属性子句或threadprivate中指定该变量
  指令,然后共享变量。动态内声明的静态变量
  共享并行区域的范围。堆分配的内存(例如,使用
  共享C或C ++中的malloc()或C ++中的new运算符)。 (指向此的指针
  但是,内存可以是私有的也可以是共享的。)具有自动存储的变量
  在并行区域的动态范围内声明的持续时间是私有的。


至于返回1的omp_get_num_threads(),我能想到的就是您没有在启用OpenMP标志的情况下进行编译。

关于c++ - OpenMP for循环会忽略num_threads子句,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4899700/

10-13 05:54