【发布时间】:2018-11-27 16:00:47
【问题描述】:
我有这个执行简单归约的 OpenMP 代码:
for(k = 0; k < m; k++)
{
#pragma omp parallel for private(i) reduction(+:mysum) schedule(static)
for (i = 0; i < m; i++)
{
mysum += a[i][k] * a[i][k];
}
}
我想创建一个与此代码等效的代码,但使用的是 OpenMP 任务。这是我通过关注this 文章所尝试的:
for(k = 0; k < m; k++)
{
#pragma omp parallel reduction(+:mysum)
{
#pragma omp single
{
for (i = 0; i < m; i++)
{
#pragma omp task private(i) shared(k)
{
partialSum += a[i][k] * a[i][k];
}
}
}
#pragma omp taskwait
mysum += partialSum;
}
}
变量partialSum被声明为threadprivate,它也是一个全局变量:
int partialSum = 0;
#pragma omp threadprivate(partialSum)
a 是一个简单的整数数组 (m x m)。
问题是当我多次运行上面的代码(带有任务的代码)时,我得到了不同的结果。
你知道我应该改变什么来完成这项工作吗?
非常感谢
【问题讨论】:
-
在您的第二个代码中,
partialSum在您的所有线程之间共享。减少处理制作mysum的私有副本并在最后将它们组合起来,但相同的处理方法没有扩展到partialSum,因此这是数据竞争的主题。您链接的幻灯片使用threadprivate()指令来解决该问题。我不确定这对你来说是否足够,但它至少可以解决数据竞争。 -
我不认为
partialSum在所有线程之间共享,因为我也将它声明为threadPrivate,就像那篇文章中一样 -
我想我在问题的最后忽略了这一点。请提供一个minimal reproducible example 展示问题。这不仅会减少此类误解的可能性,而且额外的背景可能证明很重要。
-
什么误会?我从一开始就陈述了
partialSum是threadPrivate的事实。我认为您应该从头开始阅读整个问题。
标签: c parallel-processing openmp reduction