0

我有一个简单的 Fortran 程序,其中主要组件是计算点积的 4 核 OpenMP 部分

OMP_NUM_THREADS=4
...
Do 30 k=1,lines
  co(k)=0
  si(k)=0
  co_temp=0
  si_temp=0

!$OMP PARALLEL DO PRIVATE(dotprod,Qcur) REDUCTION(+:co_temp,si_temp)
    Do 40 i=1,ION_COUNT
      dotprod=(rx(k)*x(i)+ry(k)*y(i)+rz(k)*z(i))*((2*3.1415926535)/l)
      co_temp=co_temp+COS(dotprod)*26 !Qcur/Qavg
      si_temp=si_temp+SIN(dotprod)*26 !Qcur/Qavg
     40 continue

!$OMP END PARALLEL DO

  co(k)=co_temp
  si(k)=si_temp

  q(k)= ( co(k),-si(k) )
  s(k)= s(k) +( q(k) * conjg(q(k)) )
  r(k)=r(k)+q(k)
30 continue

我对 Fortran 或其优化不是很有经验。我正在使用 xlf90_r 文件 -qsmp=omp 进行编译。使用 4 核时我只获得了大约 1/2 的加速,使用 C 的其他人在执行相同的计算时获得了几乎完美的 1/4 加速。无论 OMP 循环是在 30 还是 40 上,我得到的时间都差不多。此外,我在循环 30 以及整个程序中都计时,这个循环占用了 99.x% 的时间,所以我很确定这一点是瓶颈。我在这部分犯了任何令人震惊的缓慢错误,任何人都看到了吗?

4

3 回答 3

2

快速浏览一下您的代码,您的外部循环的每次迭代似乎都是独立的。我会让并行循环而不是内部循环。

OMP_NUM_THREADS=4
...
!$OMP PARALLEL DO PRIVATE(dotprod,Qcur,co_temp,si_temp)
Do 30 k=1,lines
  co(k)=0
  si(k)=0
  co_temp=0
  si_temp=0

  Do 40 i=1,ION_COUNT
    dotprod=(rx(k)*x(i)+ry(k)*y(i)+rz(k)*z(i))*((2*3.1415926535)/l)
    co_temp=co_temp+COS(dotprod)*26 !Qcur/Qavg
    si_temp=si_temp+SIN(dotprod)*26 !Qcur/Qavg
  40 continue

  co(k)=co_temp
  si(k)=si_temp

  q(k)= ( co(k),-si(k) )
  s(k)= s(k) +( q(k) * conjg(q(k)) )
  r(k)=r(k)+q(k)
30 continue
!$OMP END PARALLEL DO
于 2013-05-17T12:03:53.630 回答
0

可能,使用 C 语言的测试是在更好的处理器中执行的,并且您使用的是双核。如果属实,我预计不会有比 2 更好的加速。

正如@user1139069 所建议的,您应该在 k 上并行化第一个循环,以避免浪费 i 倍于创建线程组所需的运行时间。

我还认为你可能有一个错误的共享问题,因为你的线程可能在你的数组的 neibourgh 元素上工作。为了避免这种情况,我建议用类似的东西替换循环 40

   Do 40 ii=1,ION_COUNT/nCacheSize
     DO 41 i_leap=1,nCacheSize
       i=(ii-1)*nCacheSize+i_leap 
       ...
     41 CONTINUE
   40 CONTINUE

这样可以强制线程在不同的内存缓存行上工作。我认为这将加快你的代码。

请注意,例如,应将 nCacheSize 声明为常量parameter(nCacheSize=8)。您应该输入的数字取决于您的机器和变量类型。所以尝试使用 2、4、8、16、32 来找到最佳值。

于 2019-08-23T10:06:22.400 回答
-1

由于我不太明白的原因,将 OMP 放在外循环上(非常缓慢)。我无法弄清楚为什么它不能完美地并行化。但是,我能够明显加快这段代码的速度。我将 2*l*pi 变量更改为单个变量,并且只有 8 位数字。我还删除了 *26,因为我可以简单地将最终值乘以 26 或 26^2。我得到了大约 30% 的加速。不会猜到,但你去。

于 2013-06-06T20:51:29.353 回答