OpenMP Fortran粒子方法速度降低

时间:2016-06-06 15:54:46

标签: performance parallel-processing fortran openmp

在尝试优化某些代码时,我发现使用OpenMP线性增加了运行所需的时间。我试图加速的代码部分代码如下:

    CALL system_clock(count_rate=cr)
    CALL system_clock(count_max=cm)
    rate = REAL(cr)
    CALL SYSTEM_CLOCK(c1)

    DO k=1,ntotal
      CALL OMP_INIT_LOCK(locks(k)) 
    END DO  

    !$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(i,j,k)
    DO k=1,niac
      i = pair_i(k)
      j = pair_j(k)
      dvx(:,k) = vx(:,i)-vx(:,j)
      CALL omp_set_lock(locks(i))
      CALL DGER(dim,dim,-1.d0, (disp_nmh(:,j)-disp_nmh(:,i)),1, &
        (dwdx_nor(dim+1:2*dim,k)*V_0(j)),1,  particle_data(i)%def_grad,dim)
      CALL DGER(dim,dim,-1.d0, (-dvx(:,k)),1, &
        (dwdx_nor(dim+1:2*dim,k)*V_0(j)) ,1,  particle_data(i)%vel_grad(1:dim,1:dim),dim)
      CALL omp_unset_lock(locks(i))
      CALL omp_set_lock(locks(j))
      CALL DGER(dim,dim,-1.d0, (dvx(:,k)),1, &
          (dwdx_nor(3*dim+1:4*dim,k)*V_0(i)) ,1,  particle_data(j)%vel_grad(1:dim,1:dim),dim)
      CALL DGER(dim,dim,-1.d0, (disp_nmh(:,i)-disp_nmh(:,j)),1, &
        (dwdx_nor(3*dim+1:4*dim,k)*V_0(i)),1,  particle_data(j)%def_grad,dim)    
      CALL omp_unset_lock(locks(j))      
    END DO  
    !$OMP END PARALLEL DO 

    CALL SYSTEM_CLOCK(c2)
    t_el = t_el + (c2-c1)/rate
    WRITE(*,*) "Wall time elapsed: ", t_el

请注意,对于模拟,我正在测试k = 14000,我认为这是并行运行的合理候选者。据我所知,我必须使用锁来确保给出相同值“i”(但不同值为“j”)的线程无法访问正在写入的数组的相同索引。同时。我无法弄清楚我使用的BLASsudo apt-get install libblas-dev liblapack-dev)的版本是否是线程安全的。我运行了8个核心的模拟,并得到了与没有OpenMP相同的结果,所以我猜它可能是。在这种情况下,BLAS用于计算和求和许多3×3矩阵的外积。

OpenMP的实现是否是加速此代码的最佳方式?我对OpenMP知之甚少,但我的猜测是:

  • 内存遍布各处(“i”是顺序但“j”不是)
  • 启动和关闭所有线程的开销
  • 常量锁定和解锁
  • 也许是小循环尺寸(虽然我认为14000就足够了)

明显超过了性能优势。它是否正确?或者可以修改上面的代码以获得一些性能提升?

修改

我应该补充一点,上面的代码是时间积分循环的一部分。希望这能解释为什么将经过的时间相加。

0 个答案:

没有答案