我正在尝试使用openmp计算二维矩阵的平均值。这个2d矩阵实际上是一个图像。
我正在进行线程划分数据。例如,如果我有N
个线程,那么我处理的行数为N
,行数为thread0
,依此类推。
我的问题是:我可以将openmp减少条款用于“#pragma omp parallel
”吗?
#pragma omp parallel reduction( + : sum )
{
if( thread == 0 )
bla bla code
sum = sum + val;
else if( thread == 1 )
bla bla code
sum = sum + val;
}
答案 0 :(得分:20)
是的,您可以 - 还原子句适用于整个并行区域以及单个for
工作共享构造。这允许例如减少在不同并行部分完成的计算(重构代码的首选方法):
#pragma omp parallel sections private(val) reduction(+:sum)
{
#pragma omp section
{
bla bla code
sum += val;
}
#pragma omp section
{
bla bla code
sum += val;
}
}
您还可以使用OpenMP for
工作共享构造在团队中的线程之间自动分配循环迭代,而不是使用部分重新实现它:
#pragma omp parallel for private(val) reduction(+:sum)
for (row = 0; row < Rows; row++)
{
bla bla code
sum += val;
}
请注意,缩减变量是私有的,它们的中间值(即它们在parallel
区域末尾的缩减之前保持的值)只是部分且不太有用。例如,以下串行循环不能(容易地?)转换为具有缩减操作的并行循环:
for (row = 0; row < Rows; row++)
{
bla bla code
sum += val;
if (sum > threshold)
yada yada code
}
一旦yada yada code
的累计值超过sum
的值,就应该在每次迭代中执行threshold
。当循环并行运行时,sum
的私有值可能永远不会达到threshold
,即使它们的总和也是如此。
答案 1 :(得分:0)
在您的情况下,sum = sum + val
可以解释为1-d数组中的val[i] = val[i-1] + val[i]
(或2-d数组中的val[rows][cols] = val[rows][cols-1] + val[rows][cols]
),这是prefix sum计算。< / p>
缩减是前缀和的解决方案之一,您可以将缩减用于任何可交换的关联运算符,例如&#39; +&#39;,&#39; - &#39;,&#39; *&# 39;,&#39; /&#39;。