簡體   English   中英

Openmp:如何從不同的線程收集數組?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM