Ich möchte einige Fortran-Code mit OpenMP-Threads mit einem kritischen Abschnitt benchmarken. Um eine realistische Umgebung zu simulieren, habe ich vor diesem kritischen Abschnitt versucht, etwas zu laden.Code braucht viel mehr Zeit, um mit mehr als 1 Thread fertig zu sein
!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
ich diesen Code mit gfortran -fopenmp -o test.x test.f90
kompiliert und ausgeführt mit time ./test.x THREAD
Ausführen dieses Codes auf die Fadenzahl je ein seltsames Verhalten ergibt (eingestellt mit OMP_SET_NUM_THREADS): Im Vergleich zu einem Gewinde (6 ms), um die Ausführung mit mehr Threads kostet viel mehr Zeit (2 Threads: 16000ms, 4 Threads: 9000ms) auf meinem Multicore-Rechner. Was könnte dieses Verhalten verursachen? Gibt es einen besseren (aber immer noch einfachen) Weg, die Last zu generieren, ohne einige Cache-Effekte oder ähnliche Dinge auszulösen?
Edit: seltsames Verhalten: Wenn ich das Schreiben in den verschachtelten Schleifen habe, beschleunigt die Ausführung dramatisch mit 2 Threads. Wenn es auskommentiert wird, dauert die Ausführung mit 2 oder 3 Threads für immer (Schreiben zeigt eine sehr langsame Inkrementierung von Schleifenvariablen) ... aber nicht mit 1 oder 4 Threads. Ich habe diesen Code auch auf einem anderen Multicore-Rechner ausprobiert. Da dauert es für 1 und 3 Threads für immer, aber nicht für 2 oder 4 Threads.
Willkommen bei StackOverflow. Wenn Sie ein Problem mit einem Code haben, sollten Sie ein minimales, vollständiges und überprüfbares Beispiel http://stackoverflow.com/help/mcve erstellen. Was wir versuchen können, uns selbst zu lenken. –
Hat diese "andere Maschine" Hyperthreading? [Threads, die auf zwei logischen Kernen des gleichen physischen CPU-Kerns ausgeführt werden, können viel schneller kommunizieren als auf separaten physischen Kernen] (http://stackoverflow.com/questions/32979067/what-will-be-used-for-data-exchange -between-threads-ausführen-auf-einem-Kern-wi/32981256). Ich kenne Fortran nicht, also habe ich nicht einmal versucht, den Code zu überfliegen, um zu sehen, ob das Teil der Erklärung sein könnte. –