c++ - OpenMP 中的信号

标签 c++ multithreading c++11 openmp

我正在编写 more-less 的计算代码,其原理图如下:

#pragma omp parallel
{
    #pragma omp for nowait
    // Compute elements of some array A[i] in parallel

    #pragma omp single
    for (i = 0; i < N; ++i) {
        // Do some operation with A[i].
        // This time it is important that operations are sequential. e.g.:
        result = compute_new_result(result, A[i]);
    }
}

计算 A[i]compute_new_result 都相当昂贵。所以我的想法是并行计算数组元素,如果有任何线程空闲,它就会开始执行顺序操作。很有可能已经计算了起始数组元素,其他线程将由仍在执行第一个循环的其他线程提供。

但是,为了使这个概念可行,我必须实现两件事:

  1. 让 OpenMP 以替代方式拆分循环,即对于两个线程:线程 1 计算 A[0]A[2]A[4] 和线程 2:A[1]A[3]A[5]

  2. 提供一些信号系统。我正在考虑一组标志,表明 A[i] 已经被计算出来。然后 compute_new_result 应等待相应 A[i] 的标志在继续之前被释放。

对于如何实现这两个目标的任何提示,我会很高兴。我需要能够跨 Linux、Windows 和 Mac 移植的解决方案。我正在用 C++11 编写整个代码。


编辑:

我已经找到第一个问题的答案了。看起来将 schedule(static,1) 子句添加到 #pragma omp for 指令就足够了。

不过,我还在思考第二个问题的优雅解法……

最佳答案

如果您不介意将 OpenMP for 工作共享结构替换为生成任务的循环,则可以使用 OpenMP 任务来实现应用程序的两个部分。

在第一个循环中,您将创建(而不是循环 block )承担迭代计算负载的任务。然后,第二个循环的每次迭代也成为一个 OpenMP 任务。重要的部分将是同步不同阶段之间的任务。

为此,您可以使用任务依赖性(在 OpenMP 4.0 中引入):

#pragma omp task depend(out:A[0])
{ A[0] = a(); }

#pragma omp task depend(in:A[0])
{ b(A[0]); }

将确保任务 b 不会在任务 a 完成之前运行。

干杯, -迈克尔

关于c++ - OpenMP 中的信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19133922/

相关文章:

c++ - 没有函数参数的可变参数模板

c++ - 红皮书毛皮示例不渲染毛皮 (Linux/nvidia gtx675mx)

c# - 队列和并发队列的 TryDequeue 方法之间的区别

c++ - 为什么 C++11 中仍然需要 "using"指令来从基类中引入在派生类中重载的方法

c - 使用 CAS 以原子方式递增两个整数

java - ThreadlocalRandom 和 just Random

c++ - 在 c++11 中复制常量大小数组的最简洁方法

c++ - 数组指针的 vector c++

c++ - 我如何获得与打开它们的应用程序关联的端口?

c++ - 我可以使用 lambda 函数或 std::function 对象代替函数指针吗?