2 votes

Attribution de numéros de threads différents dans les do-loops OpenMP

J'ai deux do-loops dans une région parallèle OpenMP comme suit :

!$OMP PARALLEL
...
!$OMP DO
...
!$OMP END DO
...
!$OMP DO
...
!$OMP END DO
...
!$OMP END PARALLEL

Disons que OMP_NUM_THREADS=6. Je voulais exécuter la première do-loop avec 4 threads, et la seconde do-loop avec 3 threads. Pouvez-vous me montrer comment faire ? Je veux qu'ils soient à l'intérieur d'une seule région parallèle. Par exemple, dans le cas de la première boucle, je pourrais lui demander d'utiliser les numéros de fils 1, 2, 4 et 5. Merci.

5voto

Eh bien, vous pouvez ajouter le num_threads à une clause OpenMP parallel mais cela s'applique à toute directive à l'intérieur de la région. Dans votre cas, vous pourriez diviser votre programme en deux régions, comme suit

!$OMP PARALLEL DO num_threads(4)
...
!$OMP END PARALLEL DO
...
!$OMP PARALLEL DO num_threads(3)
...
!$OMP END PARALLEL DO

Bien entendu, c'est précisément ce que vous dites ne pas vouloir faire, à savoir n'avoir qu'une seule région parallèle. Mais il n'existe aucun mécanisme permettant de limiter le nombre de threads utilisés dans une région parallèle. Personnellement, je ne vois pas pourquoi quelqu'un voudrait le faire.

Quant à l'assignation de parties du calcul à des threads particuliers, là encore, non, OpenMP ne fournit pas de mécanisme pour le faire et pourquoi le voudriez-vous ?

Je suppose que je suis terriblement conventionnel, mais lorsque je vois des signes de programmes parallèles où le programmeur a essayé de prendre un contrôle précis sur les threads individuels, je vois généralement un programme avec une ou plusieurs des caractéristiques suivantes :

  • Les directives OpenMP sont utilisées pour garantir que le code s'exécute en série, avec pour résultat un temps d'exécution supérieur à celui du code série original ;
  • le programme est incorrect car le programmeur n'a pas su gérer correctement les subtilités des courses de données ;
  • il a été soigneusement arrangé pour ne fonctionner que sur un nombre spécifique de fils.

Aucune de ces situations n'est souhaitable dans un programme parallèle et si vous voulez un niveau de contrôle sur le nombre de threads et l'allocation du travail aux threads individuels, vous devrez utiliser une approche de plus bas niveau que celle fournie par OpenMP. Ces approches sont nombreuses et le fait de renoncer à OpenMP ne devrait pas vous limiter.

2voto

Hristo Iliev Points 29262

Ce que vous voulez ne peut pas être réalisé avec les constructions OpenMP existantes mais seulement manuellement. Imaginez que la boucle parallèle originale soit :

!$OMP DO
DO i = 1, 100
...
END DO
!$OMP END DO

La version modifiée, avec sélection personnalisée des fils participants, serait la suivante :

USE OMP_LIB

INTEGER, DIMENSION(:), ALLOCATABLE :: threads
INTEGER :: tid, i, imin, imax, tidx

! IDs of threads that should execute the loop
! Make sure no repeated items inside
threads = (/ 0, 1, 3, 4 /)

IF (MAXVAL(threads, 1) >= omp_get_max_threads()) THEN
   STOP 'Error: insufficient number of OpenMP threads'
END IF

!$OMP PARALLEL PRIVATE(tid,i,imin,imax,tidx)
! Get current thread's ID
tid = omp_get_thread_num()
...
! Check if current thread should execute part of the loop
IF (ANY(threads == tid)) THEN
   ! Find out what thread's index is
   tidx = MAXLOC(threads, 1, threads == tid)
   ! Compute iteration range based on the thread index
   imin = 1 + ((100-1 + 1)*(tidx-1))/SIZE(threads)
   imax = 1 + ((100-1 + 1)*tidx)/SIZE(threads) - 1
   PRINT *, 'Thread', tid, imin, imax
   DO i = imin, imax
      ...
   END DO
ELSE
   PRINT *, 'Thread', tid, 'not taking part'
END IF
! This simulates the barrier at the end of the worksharing construct
! Remove in order to implement the "nowait" clause
!$OMP BARRIER
...
!$OMP END PARALLEL

Voici trois exemples d'exécution :

$ OMP_NUM_THREADS=2 ./custom_loop.x | sort
STOP Error: insufficient number of OpenMP threads
$ OMP_NUM_THREADS=5 ./custom_loop.x | sort
 Thread           0           1          33
 Thread           1          34          66
 Thread           2 not taking part
 Thread           3 not taking part
 Thread           4          67         100
$ OMP_NUM_THREADS=7 ./custom_loop.x | sort
 Thread           0           1          33
 Thread           1          34          66
 Thread           2 not taking part
 Thread           3 not taking part
 Thread           4          67         100
 Thread           5 not taking part
 Thread           6 not taking part

Notez qu'il s'agit d'un hack terrible qui va à l'encontre des principes de base du modèle OpenMP. Je vous déconseille fortement de le faire et de vous fier à certains threads pour exécuter certaines parties du code, car cela crée des programmes hautement non-portables et entrave les optimisations d'exécution.


Si vous décidez d'abandonner l'idée d'assigner explicitement les threads qui doivent exécuter la boucle et que vous voulez seulement changer dynamiquement le nombre de threads, alors le paramètre de la taille du chunk dans la fonction SCHEDULE La clause est votre amie :

!$OMP PARALLEL
...
! 2 threads = 10 iterations / 5 iterations/chunk
!$OMP DO SCHEDULE(static,5)
DO i = 1, 10
   PRINT *, i, omp_get_thread_num()
END DO
!$OMP END DO
...
! 10 threads = 10 iterations / 1 iteration/chunk
!$OMP DO SCHEDULE(static,1)
DO i = 1, 10
   PRINT *, i, omp_get_thread_num()
END DO
!$OMP END DO
...
!$OMP END PARALLEL

Et la sortie avec 10 fils :

$ OMP_NUM_THREADS=10 ./loop_chunks.x | sort_manually :)
 First loop
 Iteration     Thread ID
       1           0
       2           0
       3           0
       4           0
       5           0
       6           1
       7           1
       8           1
       9           1
      10           1
 Second loop
 Iteration     Thread ID
       1           0
       2           1
       3           2
       4           3
       5           4
       6           5
       7           6
       8           7
       9           8
      10           9

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X