【问题标题】:Parallel for loop for addition of local matrices in OpenMP用于在 OpenMP 中添加局部矩阵的并行 for 循环
【发布时间】:2015-01-28 19:14:32
【问题描述】:

我在 n 个线程中有 n 个本地矩阵副本,比如“本地”。我想更新一个全局共享矩阵's',其元素是所有局部矩阵的相应元素的总和。 例如。 s[0][0] = local_1[0][0] + local_2[0][0]+...+local_n[0][0]。

我写了以下循环来实现它 -

#pragma omp parallel for
for(int i=0;i<rows;i++)
{   
    for(int j=0;j<cols;j++)
        s[i][j]=s[i][j]+local[i][j];
}  

这似乎不起作用。有人可以指出我哪里出错了吗?

更新示例 -

假设有 3 个线程,具有以下局部矩阵 -

线程 1 本地 = 1 2 3 4 线程 2 本地 = 5 6 7 8 线程 3 本地 = 1 0 0 1 共享矩阵将是 小号 = 7 8 10 13

【问题讨论】:

  • 它有什么作用?变量是如何定义的?结果应该如何?准备一个完整的例子。
  • 我已经用一个例子更新了这个问题。就像我提到的,变量'local'对于线程来说是本地的,而变量's'是共享的。
  • 它是做什么的,显示你的结果!将声明添加到代码中。阅读stackoverflow.com/help/mcvestackoverflow.com/help/how-to-ask,否则您的问题可能会被关闭和删除。永远不要在一个好问题中使用“它不起作用”,总是解释它的作用。
  • 我在您的代码中没有看到任何private,您如何确保它是本地的?
  • 我实际上是在计算协方差矩阵,每个线程都有一个单独的数据块。将本地副本相加以获得最终共享矩阵的过程是最后一步。我抽象出细节以使问题更简单。我已在#pragma omp parallel 指令中将“local”声明为私有,将“s”声明为共享(问题中未显示)。我没有粘贴整个代码,因为它非常庞大。谢谢

标签: matrix parallel-processing openmp


【解决方案1】:

在整个答案中,我假设您已在每个线程上正确创建了 local 的私​​有版本,作为您的问题和示例,但不是您的代码 sn-p,表明。

在您编写代码时,变量iprivate,即每个线程都有自己的副本。因为它是最外层循环的迭代变量,所以每个线程都会得到它自己的一组值来处理。假设您有 3 个线程和 3 行,那么线程 0 将获得 i0,线程 1 将获得 1,依此类推。显然(或没有)在每个线程上迭代更多行将获得更多 i 值来处理。在所有情况下,每个线程都将获得i 采用的所有值集合的不相交子集。

但是,如果线程 0 仅获得 i==0 来进行计算

s[i][j]=s[i][j]+local[i][j];

只会在线程0local0-th 行上工作。在示例中,我在线程0 上使用i,从不等于1,因此线程0local1-th 行中的值永远不会添加到行1 s.

在它们之间,3 个线程将更新 s 的 3 行,但每个线程只会添加其自己的 local 版本的行。

至于如何做你想做的事,看看this question and the accepted answer。您正在尝试数组缩减,由于here 解释的原因,C 或 C++ 不直接支持该数组。

【讨论】:

    【解决方案2】:

    如果我被允许这样做,这应该是对答案最后一段的评论。
    引用问题中的第一种方法是并行化数组填充,而不是数组缩减。根据规范 (v4 p122):
    关键构造将相关结构化块的执行限制为 一次一个线程。
    每个线程减少自己的数组部分,但只是一个接一个,本质上代码是串行运行的。求和循环位于并行区域内的唯一原因是数组对于每个线程都是本地的,这只有在填充它们时才有意义,从而受益于并行性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-31
      • 2012-05-19
      • 1970-01-01
      • 2016-07-23
      • 1970-01-01
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      相关资源
      最近更新 更多