2013-07-11 5 views
3

Je sais, il existe une fonction de base dans l'implémentation openMPI pour mapper les différents processus à différents cœurs de sockets différents (si le système possède plusieurs sockets).Affinité processeur/socket dans openMPI?

  1. --bind-to-socket (premier arrivé, premier servi)
  2. --bysocket (round-robin, sur la base de la charge balencing)
  3. --npersocket N (affecter les processus N à chaque prise)
  4. --npersocket N --bysocket (ASSIGN processus N à chaque prise mais, dans une base round-robin)
  5. --bind-to-core (lie un processus à chaque noyau de façon séquentielle)
  6. --bind-to-core --bysocket
  7. (a ssign un processus pour chaque noyau, mais ne laisser aucune prise moins utilisé)
  8. --cpus-per-proc N (processus se lient à plus d'un noyau)
  9. --rankfile (peut écrire la description complète de préférence de chaque processus)

I J'exécute mon programme openMPI sur un serveur ayant 8 sockets (10 cœurs chacun), et depuis que le multi threading est activé, il y a 160 cœurs disponibles. Je dois analyser en exécutant le programme openMPI sur différentes combinaisons de sockets/cœurs et de processus. J'attends le cas lorsque toutes les sockets sont utilisées, et que le code traite un transfert de données, pour être le plus lent possible les deux processus s'exécutent sur les coeurs d'une même socket.

So my questions are follows, 

  1. Quels sont les pires/la meilleure cartographie de cas entre le processus et les prises (chaque processus a une durée de sommeil et un transfert de données au processus racine)?

  2. Existe-t-il un moyen d'imprimer le nom des détails du socket et du noyau sur lesquels le processus est en cours d'exécution? (Je vais nous faire de ce savoir, si les processus sont eux-mêmes distribuent vraiment entre les prises)

Répondre

7
  1. Il dépend de tellement de facteurs qu'il est impossible d'obtenir une seule réponse «balle d'argent». Parmi les facteurs sont l'intensité de calcul (FLOPS/byte) et le rapport entre la quantité de données locales à la quantité de données transmises entre les processus. Cela dépend aussi de l'architecture du système. L'intensité de calcul peut être estimée analytiquement ou mesurée avec un outil de profilage comme PAPI, Likwid, etc. L'architecture du système peut être examinée en utilisant l'utilitaire lstopo, qui fait partie de la bibliothèque hwloc, fournie avec Open MPI. Malheureusement, lstopo ne peut pas vous dire à quelle vitesse chaque canal de mémoire est et à quelle vitesse/latente les liens entre les nœuds NUMA sont. Oui, il y a: --report-bindings fait que chaque rang imprime en sortie d'erreur standard le masque d'affinité qui lui est appliqué. La sortie varie un peu entre les différentes versions ouvertes MPI:

Ouvrir MPI 1.5.x montre la valeur hexadécimale du masque d'affinité:

mpiexec --report-bindings --bind-to-core --bycore

[hostname:00599] [[10634,0],0] odls:default:fork binding child [[10634,1],0] to cpus 0001 
[hostname:00599] [[10634,0],0] odls:default:fork binding child [[10634,1],1] to cpus 0002 
[hostname:00599] [[10634,0],0] odls:default:fork binding child [[10634,1],2] to cpus 0004 
[hostname:00599] [[10634,0],0] odls:default:fork binding child [[10634,1],3] to cpus 0008 

Cela montre que Le rang 0 a son masque d'affinité défini à 0001, ce qui lui permet de fonctionner uniquement sur l'UC 0. Le masque d'affinité du rang 1 est défini sur 0002, ce qui lui permet de s'exécuter sur le processeur 1 uniquement. Etc.

mpiexec --report-bindings --bind-to-socket --bysocket

[hostname:21302] [[30955,0],0] odls:default:fork binding child [[30955,1],0] to socket 0 cpus 003f 
[hostname:21302] [[30955,0],0] odls:default:fork binding child [[30955,1],1] to socket 1 cpus 0fc0 
[hostname:21302] [[30955,0],0] odls:default:fork binding child [[30955,1],2] to socket 0 cpus 003f 
[hostname:21302] [[30955,0],0] odls:default:fork binding child [[30955,1],3] to socket 1 cpus 0fc0 

Dans ce cas, les substituts de masque d'affinité entre 003f et 0fc0. 003f en binaire est 0000000000111111 et un tel masque d'affinité permet à chaque rang même d'exécuter sur les processeurs de 0 à 5. 0fc0 est 0000111111000000 et donc les rangs impairs ne sont prévu sur les CPU 5 à 11.

Ouvrir MPI 1.6.x utilise un affichage graphique plus agréable à la place:

mpiexec --report-bindings --bind-to-core --bycore

[hostname:39646] MCW rank 0 bound to socket 0[core 0]: [B . . . . .][. . . . . .] 
[hostname:39646] MCW rank 1 bound to socket 0[core 1]: [. B . . . .][. . . . . .] 
[hostname:39646] MCW rank 2 bound to socket 0[core 2]: [. . B . . .][. . . . . .] 
[hostname:39646] MCW rank 3 bound to socket 0[core 3]: [. . . B . .][. . . . . .] 

mpiexec --report-bindings --bind-to-socket --bysocket

[hostname:13888] MCW rank 0 bound to socket 0[core 0-5]: [B B B B B B][. . . . . .] 
[hostname:13888] MCW rank 1 bound to socket 1[core 0-5]: [. . . . . .][B B B B B B] 
[hostname:13888] MCW rank 2 bound to socket 0[core 0-5]: [B B B B B B][. . . . . .] 
[hostname:13888] MCW rank 3 bound to socket 1[core 0-5]: [. . . . . .][B B B B B B] 

Chaque socket est représenté graphiquement sous la forme d'un ensemble de crochets avec chaque cœur représenté par un point. Le ou les noyaux auxquels chaque rang est lié sont/sont désignés par la lettre B. Les processus sont liés au premier thread matériel uniquement.

Ouvrir MPI 1.7.x est un peu plus bavard et connaît aussi des fils de matériel:

mpiexec --report-bindings --bind-to-core

[hostname:28894] MCW rank 0 bound to socket 0[core 0[hwt 0-1]]: [BB/../../../../..][../../../../../..] 
[hostname:28894] MCW rank 1 bound to socket 0[core 1[hwt 0-1]]: [../BB/../../../..][../../../../../..] 
[hostname:28894] MCW rank 2 bound to socket 0[core 2[hwt 0-1]]: [../../BB/../../..][../../../../../..] 
[hostname:28894] MCW rank 3 bound to socket 0[core 3[hwt 0-1]]: [../../../BB/../..][../../../../../..] 

mpiexec --report-bindings --bind-to-socket

[hostname:29807] MCW rank 0 bound to socket 0[core 0[hwt 0-1]], socket 0[core 1[hwt 0-1]], socket 0[core 2[hwt 0-1]], socket 0[core 3[hwt 0-1]], socket 0[core 4[hwt 0-1]], socket 0[core 5[hwt 0-1]]: [BB/BB/BB/BB/BB/BB][../../../../../..] 
[hostname:29807] MCW rank 1 bound to socket 1[core 6[hwt 0-1]], socket 1[core 7[hwt 0-1]], socket 1[core 8[hwt 0-1]], socket 1[core 9[hwt 0-1]], socket 1[core 10[hwt 0-1]], socket 1[core 11[hwt 0-1]]: [../../../../../..][BB/BB/BB/BB/BB/BB] 
[hostname:29807] MCW rank 2 bound to socket 0[core 0[hwt 0-1]], socket 0[core 1[hwt 0-1]], socket 0[core 2[hwt 0-1]], socket 0[core 3[hwt 0-1]], socket 0[core 4[hwt 0-1]], socket 0[core 5[hwt 0-1]]: [BB/BB/BB/BB/BB/BB][../../../../../..] 
[hostname:29807] MCW rank 3 bound to socket 1[core 6[hwt 0-1]], socket 1[core 7[hwt 0-1]], socket 1[core 8[hwt 0-1]], socket 1[core 9[hwt 0-1]], socket 1[core 10[hwt 0-1]], socket 1[core 11[hwt 0-1]]: [../../../../../..][BB/BB/BB/BB/BB/BB] 

Ouvrir MPI 1.7.x remplace également les --bycore et --bysocket avec des options plus générales --rank-by <policy> option.

+0

est-ce que --report-bindings imprimerait lui-même quelque chose sur le cmd ou comment utiliser plus loin pour obtenir la liaison réelle utilisée par les processus? Il n'a rien imprimé de plus pour moi! –

+0

Chaque rang imprime sa liaison à la sortie d'erreur standard. –

+0

Je ne reçois rien sur le stderr même après avoir redirigé ceci vers stdout en utilisant ceci; char buf [BUFSIZ]; setbuf (stderr, buf); –

2

1. S'il existe une communication égale entre chaque noeud et la racine et aucun autre modèle de communication, la communication n'influencera pas les performances d'un mappage de processus spécifique> socket. (Cela suppose une topologie d'interconnexion symétrique régulière entre les sockets.) Dans le cas contraire, vous essayez généralement de placer les paires de processus avec une communication lourde proches les unes des autres dans la topologie de communication. Avec MPI sur les systèmes de mémoire partagée qui peuvent ne pas être pertinents, mais sur les clusters, il est certainement.

Cependant, l'équilibrage de charge peut également avoir un effet sur les performances du mappage. Si certains processus attendent un message/une barrière, les autres cœurs sur cette socket peuvent être capables d'utiliser une fréquence turbo plus élevée. Cela dépend fortement du comportement d'exécution de l'application. Une application composée uniquement de sommeil et de transfert n'a pas vraiment de sens.

  1. Vous pouvez utiliser libnuma/sched_getaffinity pour confirmer l'épinglage manuel du processus.

Il existe un certain nombre d'outils d'analyse de performance qui seraient utiles pour répondre à vos questions. Par exemple OpenMPI est livré avec VampirTrace qui produit une trace contenant des informations sur la communication MPI et plus encore. Vous pouvez voir avec Vampir.