2016-07-15 4 views
0

重要なセクションを持つOpenMPスレッドでいくつかのFortranコードをベンチマークします。現実的な環境をシミュレートするために、私はこのクリティカルセクションの前にいくつかの負荷を生成しようとしました。コードが1つ以上のスレッドで終了するまでに多くの時間がかかります

!Kompileraufruf: gfortran -fopenmp -o minExample.x minExample.f90 

    PROGRAM minExample 
    USE omp_lib 
    IMPLICIT NONE 
    INTEGER      :: n_chars, real_alloced 
    INTEGER      :: nx,ny,nz,ix,iy,iz, idx 
    INTEGER      :: nthreads, lasteinstellung,i 
    INTEGER, PARAMETER    :: dp = kind(1.0d0) 
    REAL (KIND = dp)    :: j 
    CHARACTER(LEN=32)    :: arg 

    nx    = 2 
    ny    = 2 
    nz    = 2 
    lasteinstellung= 10000 
    CALL getarg(1, arg) 
    READ(arg,*) nthreads 
    CALL OMP_SET_NUM_THREADS(nthreads) 
!$omp parallel 
!$omp master 
    nthreads=omp_get_num_threads() 
!$omp end master 
!$omp end parallel 
    WRITE(*,*) "Running OpenMP benchmark on ",nthreads," thread(s)" 

    n_chars = 0 
    idx = 0 
!$omp parallel do default(none) collapse(3) & 
!$omp shared(nx,ny,nz,n_chars) & 
!$omp private(ix,iy,iz, idx) & 
!$omp private(lasteinstellung,j) !& 
    DO iz=-nz,nz 
     DO iy=-ny,ny 
      DO ix=-nx,nx 
!     WRITE(*,*) ix,iy,iz 
      j = 0.0d0 
      DO i=1,lasteinstellung 
       j = j + real(i) 
      END DO 
!$omp critical 
      n_chars = n_chars + 1    
      idx = n_chars      
!$omp end critical 
      END DO 
     END DO 
    END DO 
    END PROGRAM 

私はgfortran -fopenmp -o test.x test.f90でこのコードをコンパイルし、このコードを実行するtime ./test.x THREAD でそれを実行するには、(OMP_SET_NUM_THREADSで設定)スレッドカウントに応じて、いくつかの奇妙な振る舞いを与える:1つのスレッド(6msの)と比較してより多くのスレッドで実行私のマルチコアマシンでは、より多くの時間を要します(2スレッド:16000ms、4スレッド:9000ms)。 この現象の原因は何ですか?キャッシュ効果や関連するものを実行しないでロードを生成する方がいいですが(それでも簡単です)

編集:奇妙な振る舞い:ネストされたループに書き込むと、実行速度は2スレッドで大幅に向上します。コメントアウトされていれば、2または3スレッドの実行には時間がかかります(書き込みは非常に遅いループ変数の増加を示します)... 1スレッドまたは4スレッドでは実行できません。私はこのコードを別のマルチコアマシンでも試してみました。そこに1と3つのスレッドが永遠にかかるが、2つか4つのスレッドではない。

+3

Welcome to StackOverflow。コードに問題がある場合は、最小、完全、および検証可能な例http://stackoverflow.com/help/mcveを作成する必要があります。私たちは自分自身を実行しようとすることができます。 –

+0

この「他のマシン」にハイパースレッディングがありますか? [同じ物理CPUコアの2つの論理コアで動作するスレッドは、別々の物理コアよりもずっと高速に通信できます](http://stackoverflow.com/questions/32979067/what-will-be-used-for-data-exchangeスレッド間実行中は1コア/ 32981256)。私はFortranを知らないので、これが説明の一部であるかどうかを調べるためにコードをスキップしようとしなかった。 –

答えて

2

表示されているコードが実際に完了している場合は、並列セクションのloadSetの定義が不足しています(private)。定義されていないループです。

    DO i=1,loadSet 
        j = j + real(i) 
       END DO 

は、完全に任意の回数の反復を取ることができます。

値がコード内のどこかで定義されている場合、表示されない場合は、privateの代わりにfirstprivateが必要になる可能性があります。

+0

変数が定義されました。問題は私がそれを私的なものとして宣言したことでした。ありがとう! –

関連する問題