重要なセクションを持つ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つのスレッドではない。
Welcome to StackOverflow。コードに問題がある場合は、最小、完全、および検証可能な例http://stackoverflow.com/help/mcveを作成する必要があります。私たちは自分自身を実行しようとすることができます。 –
この「他のマシン」にハイパースレッディングがありますか? [同じ物理CPUコアの2つの論理コアで動作するスレッドは、別々の物理コアよりもずっと高速に通信できます](http://stackoverflow.com/questions/32979067/what-will-be-used-for-data-exchangeスレッド間実行中は1コア/ 32981256)。私はFortranを知らないので、これが説明の一部であるかどうかを調べるためにコードをスキップしようとしなかった。 –