任务不会使用OpenMP并行运行。我的设置或我的代码错了吗?

时间:2017-11-13 12:57:19

标签: c++ multithreading task openmp

我正在使用OpenMP成功并行化我的c ++代码中的循环。我试过了 进一步使用OpenMP任务。不幸的是我的代码行为 真奇怪,所以我写了一个最小的例子,发现了一个问题。 我想定义几个任务。每个任务应该执行一次 通过一个空闲的线程。 不幸的是,我只能使所有线程执行每个任务或 只有一个线程按顺序执行所有任务。

这是我的代码基本上按顺序运行:

int main() {
    #pragma omp parallel
    {
        int id, nths;
        id = omp_get_thread_num();
        #pragma omp single nowait
        {
            #pragma omp task
            cout<<"My id is "<<id<<endl;
            #pragma omp task
            cout<<"My id is "<<id<<endl;
            #pragma omp task
            cout<<"My id is "<<id<<endl;
            #pragma omp task
            cout<<"My id is "<<id<<endl;
        }
    }
    return 0;
}

只有工人0出现并给他的身份四次。 我希望看到“我的身份证是0;我的身份证是1;我的身份证是2;我的身份证是3; 如果我删除#pragma omp single我得到16条消息,所有线程都会执行 每一个cout

这是我的OpenMP设置的问题还是我没有得到什么 任务?我在Ubuntu上使用gcc 6.3.0并正确使用-fopenmp标志。

1 个答案:

答案 0 :(得分:0)

您对OpenMP任务的基本用法(parallel - &gt; single - &gt; task)是正确的,您误解了变量的数据共享属性的复杂性。

首先,您可以通过在任务中移动omp_get_thread_num()而不是访问id来轻松确认您的任务是由不同的线程运行。

您的示例中发生了什么,idprivate构造中隐式parallel。但是,在任务内部,它隐含firstprivate。这意味着,该任务从执行single构造的线程中复制值。对类似问题进行更详尽的讨论can be found here

请注意,如果在嵌套任务构造中使用private,则它与外部并行构造中的private变量不同。简单地说,private不是指线程,而是构造。这与threadprivate的区别。但是,threadprivate不是构造的属性,而是它自己的指令,仅适用于具有块范围的文件范围,命名空间范围或静态变量的变量。