Je veux comparer un code Fortran avec des threads OpenMP avec une section critique. Pour simuler un environnement réaliste, j'ai essayé de générer de la charge avant cette section critique.Le code prend beaucoup plus de temps pour terminer avec plus de 1 thread
!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
Je compilé ce code avec gfortran -fopenmp -o test.x test.f90
et exécuté avec time ./test.x THREAD
exécution de ce code donne un comportement étrange en fonction du thread count (ensemble avec OMP_SET_NUM_THREADS): par rapport à un fil (6ms) l'exécution avec plus de fils coûte beaucoup plus de temps (2 threads: 16000ms, 4 threads: 9000ms) sur ma machine multicœur. Ce qui pourrait causer ce problème? Existe-t-il une meilleure façon de générer de la charge (mais toujours facile) sans exécuter certains effets de cache ou des choses connexes? Comportement étrange: si j'ai l'écriture dans les boucles imbriquées, l'exécution accélère considérablement avec 2 threads. Si c'est commenté, l'exécution avec 2 ou 3 threads prend une éternité (l'écriture montre une incrémentation très lente des variables de boucle) ... mais pas avec 1 ou 4 threads. J'ai essayé ce code également sur une autre machine multicœur. Là, il prend pour 1 et 3 fils pour toujours mais pas pour 2 ou 4 fils.
Bienvenue sur StackOverflow. Si vous avez un problème avec un code, vous devez créer un exemple minimal, complet et vérifiable http://stackoverflow.com/help/mcve. Lequel nous pouvons essayer de courir nous-mêmes. –
Est-ce que cette "autre machine" a de l'hyperthreading? [Les threads s'exécutant sur deux cœurs logiques du même noyau de CPU physique peuvent communiquer beaucoup plus rapidement que sur des cœurs physiques séparés] (http://stackoverflow.com/questions/32979067/what-will-be-used-for-data-exchange -entre-threads-sont-exécution-sur-un-core-wi/32981256). Je ne connais pas Fortran, donc je n'ai même pas essayé d'écrémer le code pour voir si cela pouvait faire partie de l'explication. –