[英]Openmp: How to collect an array from different threads?
我是OpenMP新手,但遇到了問題! 我有一個在循環中求和的數組,但是在並行化該數組時遇到了問題。 你能建議怎么做嗎? 主循環如下所示:
REAL A (N) ! N is an integer
!$OMP PARALLEL
DO I=1,10 ! just an illustration
DO J=1,10 ! can't post real code sorry, illegal
!$OMP DO
DO K=1,100
call messy_subroutine_that_sums_A(I,J, K, A) ! each thread returns its own sum
! each thread returns its own A right? and needs to summed quickly
END DO
!$OMP END DO
END DO
END DO
SUBROUTINE messy_subroutine_that_sums_A(I,J, K, A)
REAL A(N) ! an array
! basically adds some stuff to the previous value of A
A=A+junk ! this is really junk
END SUBROUTINE messy_subroutine_that_sums_A
我的問題是我從所有線程收集A
的所有嘗試均失敗了。 如果您發現A
也通過外部循環求和。 從所有數組中收集A
作為總和的正確且快速的過程是什么? 其次,我的問題不僅僅是一個Fortran問題,它同樣適用於C和C ++。 這是一個概念上的問題。
實際上,OpenMP確實支持減少C,C ++中的數組(最近在OpenMP 4.1注釋草稿版本中聲明),以及減少原因。
並非所有實現都支持此功能,因此最好先檢查編譯器是否支持此功能。 要查看計算是否正確,可以先將A=A+junk
放入關鍵部分:
!$omp critical
A=A+junk
!$omp end critical
在OMP DO循環之后,這應該在所有線程中給您相同的正確答案。
然后,您可以使用數組精簡而不是OMP DO循環上的critical
來優化性能,在循環后的所有線程中再次具有相同的正確答案。
然后,您可以進一步優化性能,將減少量移至OMP PARALLEL,但是在這種情況下,您將無法檢查所有線程中的值,因為所有線程將與數組A的私有副本一起使用,因此具有不同的部分值。 最終正確答案僅在OMP PARALLEL之后在主線程中可用。
請注意,您不需要在Fortran中將循環迭代變量聲明為私有,因為它們應自動設為私有。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.