我试图将可以找到的FEM1D代码here并行化。与之相关的部分是:
for ( i = 1; i < nu - 1; i++ )
{
adiag[i] = adiag[i] - aleft[i] * arite[i-1];
arite[i] = arite[i] / adiag[i];
}
只需添加
#pragma omp parallel for
循环之前不起作用,我不知道为什么。我假设它是因为其他线程需要更新数组,但由于我是私有的,线程不应该更新另一个线程所需的任何东西?
我尝试制作新的变量使它们成为私有但我很确定它与更新adiag和arite数组有关,所以我尝试了flush指令,它指定所有线程对所有共享对象都有相同的内存视图,但没有骰子。
#pragma omp parallel for private(i,ad,al,ar)
for ( i = 1; i < nu - 1; i++ )
{
#pragma omp flush(adiag, arite, aleft)
ad = adiag[i];
al = aleft[i];
ar = arite[i-1];
adiag[i] = ad - al * ar;
ar = arite[i];
ad = adiag[i];
arite[i] = ar / ad;
}
所以我非常喜欢这里,任何帮助我的建议都会非常感激。
编辑:by不起作用我的意思是在完成循环后,数组adiag和arite被错误填写
EDIT2:我已经开始使用循环
了#pragma omp parallel for ordered
for ( i = 1; i < nu - 1; i++ )
{
#pragma omp ordered
adiag[i] = adiag[i] - aleft[i] * arite[i-1];
arite[i] = arite[i] / adiag[i];
}
但我认为它首先打败了循环并行化的目的
答案 0 :(得分:1)
我认为你不能转换这个循环。您具有循环数据依赖性。通常当你有一个可以转换的循环时,你可以交换命令顺序,并解决循环问题,如下所示:
for ( i = 1; i < nu - 1; i++ )
{
arite[i-1] = arite[i-1] / adiag[i-1];
adiag[i] = adiag[i] - aleft[i] * arite[i-1];
}
虽然,当你这样做时,你需要使用另一个线程计算的值。我可能错了......