2013-09-30 47 views
1

我面臨的問題是概述如下:OpenMP的子程序調用線程中

module k 
    integer :: l,m 
end module k 

program p4 
    use k 
    integer :: i,j,omp_get_thread_num,cr 

    i = 2 
    j = 3 

    !$omp parallel num_threads(2) shared(l,m) private(i,j,cr) 
    cr = omp_get_thread_num() 
    if (cr == 0) goto 1111 
    call sub1(i) 
    write(*,*) l 
    goto 2222 
1111 call sub2(j) 
    write(*,*) m 
2222 continue 
    !$omp end parallel 
end program p4 

subroutine sub1(a) 
    use k 
    integer :: a 

    l = a**2 
    write(*,*) 'entered sub1' 
end subroutine sub1 

subroutine sub2(b) 
    use k 
    integer :: b 

    m = b**2 
    write(*,*) 'entered sub2' 
end subroutine sub2 

我試圖並行串行,(其中並行後看起來就像上面寫的)。我基本上需要執行兩次相同的操作。所以,理想的情況是,我所要的輸出是

entered sub1 
4 
enterer sub2 
9 

但輸出

entered sub2 
      0 
entered sub1 
    923239424 

我新的並行編程,(我的實際問題是一個我有一個更復雜的版本概括)。任何人都可以指出錯誤並提出改進建議。由於

+0

與上述同意。你有什麼是不可讀的。它是Haskell嗎? – Adam

+0

@亞當:哈斯克爾?不,它顯然是Fortran。關鍵線索:「繼續」聲明。 –

+0

@IraBaxter啊是的,我也看到了GOTO。謝謝你的提示。也許我應該停止做這麼好的避免Fortran和Haskell的工作。 – Adam

回答

7

OpenMP的private變量不是給定的初始值,因此這兩個調用sub1sub2用的ij隨機值進行。你是什​​麼東西(可能)尋找的是firstprivate代替:

!$omp parallel num_threads(2) shared(l,m) private(cr) firstprivate(i,j) 
... 
!$omp end parallel 

firstprivate初始化與在主線程對應的變量對進入並行區域中值的每個專用副本。

順便說一下,在Fortran 90中實現IF/THEN/ELSE/ENDIFIF/GOTO/CONTINUE,後來被認爲是很多糟糕的編程風格。您應該使用OpenMP部分代替:

!$omp parallel sections num_threads(2) shared(l,m) private(cr) firstprivate(i,j) 
    !$omp section 
    call sub1(i) 
    write(*,*) l 
    !$omp section 
    call sub2(j) 
    write(*,*) m 
!$omp end parallel sections 
+0

不確定,但也許你應該刪除'!$ omp end section'。 gfortran不承認這一點,它不在[this](https://computing.llnl.gov/tutorials/openMP/#SECTIONS)教程中。 – 2013-09-30 12:09:46

+0

你是對的 - 只是看看標準。我已經完全機械地添加了它們。 –