1

Je fais des recherches sur le laboratoire d'électromagnétisme computationnel avec des supercalculateurs. Ici, nous travaillons avec des clusters pour résoudre des problèmes comprenant plus de 500M d'inconnues. À ce stade, nous avons un problème avec la parallélisation de tous ces calculs. Jusqu'à présent, nous travaillions avec MPI pour communiquer entre les nœuds, cependant, nous sommes sur le point de décider d'utiliser OpenMP pour permettre la communication entre les processeurs dans un nœud en termes de bénéfices d'OpenMP. Néanmoins, nous ne pouvions obtenir aucune efficacité de openMP (probablement à cause du faux codage). En fait, le fait est que je ne sais pas quel est le problème avec le code que je vais donner.Problème OpenMP et de parallélisation

Cela a pris le même temps avec du code pur séquentiel sans aucune directive OpenMP. Lorsque j'utilise la commande 'top' 8 processeurs travaillaient avec% 100 performance pendant la section paralllel.

gfortran - version | head -1 GNU Fortran (GCC) 4.1.2 20.080.704 (Red Hat 4.1.2-46)

PROGRAM dotproduct 
    USE omp_lib 
    IMPLICIT none 

    INTEGER ::h,m,i,TID,NTHREADS,j,ierr 

    REAL :: start,end 
    REAL, ALLOCATABLE, DIMENSION(:,:) :: a 
    REAL, ALLOCATABLE, DIMENSION(:) :: x 
    REAL, ALLOCATABLE, DIMENSION(:) :: b 

    m= 20000 
    OPEN(UNIT=1,FILE='matrix20000.dat',STATUS='UNKNOWN') 
    OPEN(UNIT=2,FILE='vector20000.dat',STATUS='UNKNOWN') 

    ALLOCATE(a(m,m)) 
    ALLOCATE(x(m)) 
    ALLOCATE(b(m)) 
    REWIND(1) 
    REWIND(2) 

    WRITE(*,*) ' Reading is just started' 

    READ(1,*), a(:,:) 
    READ(2,*), x(:) 

    WRITE(*,*) ' Reading is over' 
    WRITE(*,*) ' Calculating will be started after parallelization' 

    !$OMP PARALLEL PRIVATE(i,TID,j),SHARED(NTHREADS,m,a,x,b) 
    TID= omp_get_thread_num() 
    IF(TID == 0) THEN 
     NTHREADS = OMP_GET_NUM_THREADS() 
     PRINT*, 'Starting matrix multiple example with', NTHREADS 
    END IF 
    CALL cpu_time(start) 
    !$OMP DO 
      DO i=1, m 
      b(i)= 0 
      DO j=1, m 
       b(i) = b(i)+ a(i,j)*x(j) 
      END DO 
      END DO 
    !$OMP END DO 
    !$OMP END PARALLEL 
    CALL cpu_time(end) 

    WRITE(*,*) end-start,' seconds' 

    !DO i=1,m 
    ! WRITE(*,*) b(i) 
    !END DO 

    DEALLOCATE(a)      !----Deallocation 
    DEALLOCATE(x) 
    DEALLOCATE(b) 


    END PROGRAM dotproduct 
+2

Le support OMP Redhat rétroportage gcc 4.1 était connu pour des performances médiocres. Je recommande de regarder un compilateur plus moderne avant de faire quoi que ce soit d'autre. – talonmies

+1

Mai gcc 4.1 est la raison principale de cette mauvaise performance. En fait, est-il correct de l'appeler "mauvaise performance", car il semble qu'il n'y ait pas de paralellisation .. – Yigit

+0

Je viens de penser, comment mesurez-vous exactement le temps d'exécution? Si vous utilisez la sortie de cpu_time, vous obtiendrez le temps cumulé de tous les threads. Si vous utilisez MPI de toute façon, vous devriez plutôt utiliser MPI_wtime pour obtenir le temps réel réel. En ce qui concerne les compilateurs, je ne crois pas que l'implémentation de GCC serait trop mauvaise, même en 4.1, le changement de compilateur pourrait encore améliorer la mise à l'échelle d'OpenMP. – haraldkl

Répondre

0

On dirait un problème d'accès à la mémoire en conflit. Tous les processus accèdent au x (j) partagé. Bien que ce ne soit pas une vraie solution, vous pouvez essayer de dupliquer x sur chaque thread, pour voir si cela aide.

+0

Que voulez-vous dire en dupliquant x sur chaque thread, comment puis-je? – Yigit

+0

Avoir quelque chose comme x (j, tid) avec le même contenu pour chaque tid. – haraldkl

+0

Peut-être que ceci: http://people.sc.fsu.edu/~jburkardt/f_src/mxv_open_mp/mxv_open_mp.f90 est également intéressant pour vous, ils ont une version de partage du vecteur matriciel multiplier avec OpenMP. – haraldkl

1

Erreur classique - Cpu_time mesure généralement le temps CPU total, ce qui signifie qu'il est additionné sur tous les threads! Essayez donc de mesurer l'heure du mur avec system_clock ou similaire et voyez ce que vous obtenez.

BTW - pourquoi nthreads est-il partagé? Il est préférable de garder autant que possible privé

(désolé si cela apparaît deux fois, d'abord l'effort ...)