【问题标题】:Task wont run parallel using OpenMP. Is my setup or my code wrong?任务不会使用 OpenMP 并行运行。我的设置或我的代码错了吗?
【发布时间】:2017-11-13 12:57:18
【问题描述】:

我成功地使用 OpenMP 在我的 c++ 代码中并行化 for 循环。我试过了 更进一步并使用 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 出现并给出了他的 id 四次。 我希望看到“我的 id 是 0;我的 id 是 1;我的 id 是 2;我的 id 是 3; 如果我删除 #pragma omp single 我收到 16 条消息,所有线程都会执行 每一个cout

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

【问题讨论】:

  • Single 意味着每个任务只能由一个任务处理。所以每个线程都应该处理其中一项任务。
  • 但是如何让单个线程并行处理每个任务?
  • @tobi303, parallel(启动一组线程)-single(一个线程负责创建任务)-task(独立执行)是 OpenMP 中的标准模式。
  • @Zulan 所以我链接的文档是错误的?我不知道,这就是我发现的,也许我误解了它......
  • @tobi303 文档是正确的,但您还可以查看 task 构造的文档以了解组合。

标签: c++ multithreading task openmp


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2021-02-06
    • 2015-03-06
    • 1970-01-01
    • 2019-10-24
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 2012-07-19
    • 1970-01-01
    相关资源
    最近更新 更多