PARALLEL DO是否有关键?

时间:2013-01-31 18:42:46

标签: fortran openmp

关注代码的并行部分,首选哪个选项?更好的解决方案?我试图平均实现do_something

的独立实现

选项1:使用CRITICAL

  resultado%uno = 0.d0
  !$OMP PARALLEL DO shared(large) private(i_omp) schedule(static,1)
  do i_omp=1, nthreads
     call do_something(large, resultadoOmp(i_omp))
     !$OMP CRITICAL (forceloop)
     resultado%uno = resultado%uno + resultadoOmp(i_omp)%uno
     !$OMP END CRITICAL (forceloop)
  enddo
  !$OMP END PARALLEL DO
  resultado%uno  = resultado%uno/nthreads

选项2:避免CRITICAL(和ATOMIC

  !$OMP PARALLEL DO shared(large) private(i_omp) schedule(static,1)
  do i_omp=1, nthreads
     call do_something(large, resultadoOmp(i_omp))
  enddo
  !$OMP END PARALLEL DO

  uno = 0.d0
  !$OMP PARALLEL DO shared(resultado) private(i_omp) schedule(static,1) &
  !$OMP & REDUCTION(+:uno)
  do i_omp=1, nthreads
     uno = uno + resultadoOmp(i_omp)%uno
  end do
  !$OMP END PARALLEL DO
  resultado%uno  = uno/nthreads

我在这方面无法使用REDUCTION(+:resultado%uno)REDUCTION(+:resultado),只允许使用数字类型。

IMO这种方法的缺点是必须使用线程数来确定派生的条带resultadoOmp的大小。优点是可以避免可能影响性能的CRITICAL子句,我是对的吗?

1 个答案:

答案 0 :(得分:0)

  

IMO的这种方法的缺点是必须使用线程数来确定派生的tipe resultadoOmp的大小。优点是可以避免可能影响性能的CRITICAL子句,我是对的吗?

是的,你是对的。看起来你无论如何都要使用线程数来确定resultadoOmp的尺寸,所以这不是一个真正的劣势吗?第二部分的性能确实应该更好,尽管两个平行区域可能会再次消耗这种优势。因此,您应该只对两个部分使用单个并行区域。根据do_something的运行时间,我甚至可以完全忽略还原操作的并行性,只需在并行计算所有uno条目后在单个线程上进行求和:

!$OMP PARALLEL DO shared(large) private(i_omp) schedule(static,1)
do i_omp=1, nthreads
   call do_something(large, resultadoOmp(i_omp))
end do
!$OMP END PARALLEL DO

resultado%uno = sum(resultadoOmp(:)%uno)/nthreads

您需要使用实际设置来衡量各种实现,以得出结论。