我有执行以下简化操作的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 Tasks创建与该代码等效的代码。这是我根据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)。
问题是,当我多次运行上面的代码(带有任务的代码)时,我得到的结果是不同的。
您对我应该进行哪些更改以使它起作用有想法吗?
谢谢你
答案 0 :(得分:1)
private
变量未初始化(至少不通过其外部值初始化)。 i
应该是firstprivate
。
如果您只是摆脱private(i) shared(k)
,则默认情况下一切正确。 k
来自parallel
部分之外,因此在shared
部分中隐含parallel
。这也使其在任务生成构造中隐式shared
。目前i
也已共享/共享。如果改为在本地定义(for (int i...
,则它在private
部分隐式变成parallel
,在任务生成结构中隐式变成firstprivate
。
您还应该添加
#pragma omp atomic
mysum += partialSum;
另一方面,您不一定需要taskwait
(请参阅this answer)
请注意,演讲正确使用了firstprivate
。