【问题标题】:OpenMP with nested loops带有嵌套循环的 OpenMP
【发布时间】:2016-07-27 03:25:52
【问题描述】:

我有几个函数应该连续应用于某些结构的矩阵。对于单线程,我使用以下代码:

for(int t = 0; t < maxT; ++t)
{
    for(int i = 0; i < maxI; ++i)
        for(int j = 0; j < maxJ; ++j)
            function1(i, j);

    for(int i = 0; i < maxI; ++i)
        for(int j = 0; j < maxJ; ++j)
            function2(i, j);
}

现在我正在尝试并行化该代码:

#pragma omp parallel
{
    for(int t = 0; t < maxT; ++t)
    {
        #pragma omp single
        function3(); // call this function once (once for each iteration of t)
        #pragma omp for
        for(int i = 0; i < sizeI; ++i)
            for(int j = 0; j < sizeJ; ++j)
                function1(i, j);

        #pragma omp for
        for(int i = 0; i < sizeI; ++i)
           for(int j = 0; j < sizeJ; ++j)
               function2(i, j);
    }
}

正确吗? 它是否以重用线程的方式工作(不在主循环中创建新的线程组)?

更新:显式障碍确实没有必要。

实际上,当我问这个问题时,我似乎很困惑——代码示例可以正常工作。现在的问题是:是否可以在 #pragma omp parrallel 之后调用一次函数(代码中的注释行)(不要在每次迭代的每个线程中调用 function3)。有 #pragma omp atomic 可以调用增量运算符和其他一些运算符,但是如果我想调用任意函数的单个实例(或者,通常是执行代码块)?

马克的评论。我假设我将在我的并行函数中处理数据竞争。这里唯一的问题是:使用 OpenMP 时,stl 容器不是简单的线程安全的吗?即,如果我想从多个线程的 std::list 中 push_back(),我仍然需要手动锁定该列表。

更新 2:我发现要在并行部分运行单个操作,需要使用 #pragma omp single。所以,这个问题已经结束了。

【问题讨论】:

  • 正确吗?可能。可能不是。您的功能似乎可能通过副作用来运行。这些副作用可能会导致数据竞争......

标签: c++ openmp


【解决方案1】:

是的,这将创建一个并行区域,每个线程将在外部循环上迭代 t,并在线程之间拆分 i 循环的迭代工作。

请注意,#pragma omp for 在其末尾有一个隐式屏障,因此您无需同时编写显式屏障。可以使用nowait 子句(即#pragma omp for nowait)删除此隐式障碍。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多