OpenMP:重写一个for循环,以便它可以并行化?

时间:2015-09-23 13:30:49

标签: c arrays multithreading loops openmp

我试图将可以找到的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];
}

但我认为它首先打败了循环并行化的目的

1 个答案:

答案 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];
}

虽然,当你这样做时,你需要使用另一个线程计算的值。我可能错了......