2015-09-09 96 views
4

在我嘗試移植到OpenMP的代碼中,我有一個嵌套在外部循環中的並行化循環。根據外部循環的迭代,我想要一個特定的數組是sharedreduction(+)。有沒有辦法在Fortran中做到這一點?OpenMP中的條件共享狀態

這裏是我想要什麼樣機:

do i = 1, 2 
    !$omp if(i.eq.1) parallel do reduction(+:foo) 
    !$omp if(i.eq.2) parallel do shared(foo) 
    do j = 1,j_max 
    work on foo 
    enddo 
    !$omp end parallel 
enddo 

openMP conditional pragma "if else"的討論表明,調度不能在執行期間修改。這也是共享/私人/減少/等的情況?

一個明顯的行爲是創建foo_1(reduce:+)和foo_2(共享),在第一次迭代之後將foo_1複製到foo_2,然後在if循環中的if語句引用正確陣列。但這不是非常優雅。我希望有一個更好/更聰明/更乾淨的方式來做到這一點。

編輯:爲缺乏想象力,這是我的替代

do i = 1, 2 
    !$omp parallel do reduction(+:foo_1), shared(foo_2) 
    do j = 1,j_max 

    if(i .eq. 1) then 
     work on foo_1 
    else 
     work on foo_2 
    endif 

    enddo 
    !$omp end parallel 

    foo_2 = foo_1 
enddo 
+0

在你的第一個例子中,你有兩個嵌套的指令打開兩個嵌套的平行部分。我想你最後需要兩個'!$ omp end parallel'指令。 –

+2

是否有一個原因,你不想刪除外循環,只是寫兩個單獨的OMP啓用for循環?沒有任何嵌套,這個問題是微不足道的。 – NoseKnowsAll

+0

除非你討厭表現,否則在循環之外分支。 – Jeff

回答

1

的僞代碼版本,你不介意有兩個平行的區域,你可以使用孤立的指令 - 我發現這些偉大的組織的整體結構大型OpenMP代碼。我的意思是這樣

i = 1 
    !$omp parallel shared(i, foo, ...) 
    Call do_the_work(i, foo, ...) 
    !$omp end parallel 
    i = 2 
    !$omp parallel shared(i, ...) reduction(+:foo) 
    Call do_the_work(i, foo, ...) 
    !$omp end parallel 

... 

    Subroutine do_the_work(i, foo, ...) 
     !$omp do 
     do j = 1,j_max 
     work on foo 
     enddo 
    End Subroutine do_the_work 

如果像你說的,它可能希望通過自己在一個或多個程序反正並行區域就有多大。

+0

謝謝,但爲了我的目的,使用兩個數組比將中間區併入子例程更清潔。 – Grundulum