OpenMP性能低下

时间:2015-09-29 11:22:55

标签: c openmp

我试图在我的程序中并行化一个循环,所以我搜索了多线程。首先,我看了一下POSIX多线程编程教程,它太复杂了,所以我试着做一些更简单的事情。我试过OpenMP。我已经成功并行化了我的代码,但执行时间问题比串行案例更糟糕。这低于我的程序的一部分。我希望你告诉我这是什么问题。我应该指定共享哪些变量以及哪些变量是私有的?我怎么知道每个变量的种类?我希望你回答我,因为我在许多论坛上搜索过,但我仍然不知道该怎么做。

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <omp.h>
#define D                0.215         // magnetic dipolar constant

main()
{
  int     i,j,n,p,NTOT = 1600,Nc = NTOT-1;
  float   r[2],spin[2*NTOT],w[2],d;
  double  E,F,V,G,dU;
  .
  .
  .
  for(n = 1; n <= Nc; n++){
    fscanf(voisins,"%d%d%f%f%f",&i,&j,&r[0],&r[1],&d);
    V = 0.0;E = 0.0;F = 0.0;
    #pragma omp parallel num_threads(4)
    {
      #pragma omp for schedule(auto)
      for(p = 0;p < 2;p++)
      {
        V += (D/pow(d,3.0))*(spin[2*i-2+p]-w[p])*spin[2*j-2+p];
        E += (spin[2*i-2+p]-w[p])*r[p];
        F += spin[2*j-2+p]*r[p];
      }
    }
    G = -3*(D/pow(d,5.0))*E*F;
    dU += (V+G);
   }
   .
   .
   .
 }//End of main()

1 个答案:

答案 0 :(得分:2)

您只使用2次迭代并行化循环:p=0p=1。 OpenMP&#39;} omp for的工作方式是将并行团队中的线程(您已定义为4个线程)之间的循环迭代分开,让他们解决问题的一部分并行。

只需2次迭代,你的2个线程将处于空闲状态。最重要的是,实际上找出哪些线程可以解决问题的哪一部分需要开销。如果你的实际循环不需要很长时间(在这种情况下它显然不会),那么开销将比你从并行化中获得的好处花费更多。

更好的策略通常是尽可能将最外层循环与OpenMP并行化,以便解决均匀分割工作和减少(相对)开销的问题。或者,您可以使用OpenMP 4.0的omp simd命令在最低循环级别进行并行化。

最后,您没有正确计算变量VEF。因为它们是从迭代到迭代的总和,所以您应该将它们全部定义为具有reduction(+:V)的简化变量。如果你现在得到正确答案,我会感到惊讶。

(同样,高性能标记说:确保您为计划的执行时间执行计时,而不是计划的CPU时间执行。这通常使用omp_get_wtime()完成。)