我有n个本地副本的矩阵,比如说'本地''在n个线程中。我想更新一个全球共享矩阵'其元素是所有局部矩阵的相应元素的总和。 例如。 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个线程,具有以下本地矩阵 -
thread 1 local = 1 2 3 4 thread 2 local = 5 6 7 8 thread 3 local = 1 0 0 1 shared matrix would then be s = 7 8 10 13
答案 0 :(得分:0)
在整个答案中,我假设您已经在每个帖子上正确创建了local
的私有版本作为您的问题和示例,但不是您的代码段,请指明。
当您编写代码时,变量i
为private
,即每个线程都有自己的副本。因为它是最外层循环的迭代变量,所以每个线程都会获得它自己的一组值来处理。假设您有3个线程和3个行,则线程0
将获得i
值0
,线程1
将获得1
,依此类推。显然(或没有)在每个线程上迭代更多行会获得更多的i
值。在所有情况下,每个线程将获得i
所有值集的不相交子集。
但是,如果线程0
仅获得i==0
来处理计算
s[i][j]=s[i][j]+local[i][j];
只能在线程0
上的local
行0
上工作。在我使用i
的示例中,在线程0
上,永远不等于1
所以1
- local
行0
上的值{ {1}}永远不会添加到1
的行s
。
在它们之间,3个线程将更新s
的3行,但每个行只会添加自己的local
版本的行。
至于如何做你想做的事,请看看this question and the accepted answer。您正在尝试数组缩减,由于here解释的原因,在C或C ++中不直接支持。
答案 1 :(得分:0)
如果我被允许这样做,这应该是对答案最后一段的评论
引用问题中的第一个方法是并行化数组填充而不是数组缩减。根据规格(v4 p122):
关键构造将相关结构化块的执行限制为a
一次单线程。
每个线程都减少了它自己的数组部分,但只有一个接一个,实质上代码是串行运行的。求和循环位于并行区域内的唯一原因是数组对于每个线程都是局部的,只有当它们从并行性中获益时才有意义。