mémoire partagée, MPI et systèmes de file d'attente

mon application unix / windows C++ est déjà parallélisée en utilisant MPI: le travail est divisé en n cpus et chaque morceau est exécuté en parallèle, très efficace, très bonne mise à l'échelle de la vitesse, le travail est fait correctement.

mais certaines données sont répétées dans chaque processus, et pour des raisons techniques ces données ne peuvent pas être facilement divisées sur MPI (...). Par exemple:

  • 5 Go de données statiques, exactement la même chose chargés pour chaque processus
  • 4 Go de données qui peuvent être distribué en MPI, plus les CPU sont utilisés, plus cette mémoire est petite par CPU.

sur un travail 4 CPU, cela signifierait au moins une charge RAM de 20 Go, la plus grande partie de la mémoire est 'gaspillée', c'est terrible.

je pense qu'en utilisant la mémoire partagée pour réduire la charge globale, le morceau" statique " ne serait chargé qu'une fois par ordinateur.

Donc, la question principale est:

  • Existe-t-il un moyen standard MPI de partager la mémoire sur un noeud? une sorte de facilement disponibles + accès gratuit à la bibliothèque ?

    • Si non, je voudrais utiliser boost.interprocess et utiliser les appels MPI pour distribuer les identificateurs de mémoire partagée locaux.
    • la mémoire partagée serait lue par un "maître local" sur chaque noeud, et partagée en lecture seule. Pas besoin de sémaphore/synchronisation, car cela ne changera pas.
  • Aucun gain de performance ou de problèmes particuliers à se méfier?

    • (Il n'y aura "strings" ou structures de données trop bizarres, tout peut être ramené à des tableaux et des pointeurs de structure)
  • Le travail sera exécuté dans un système de mise en file D'attente PBS (ou SGE), dans le cas d'un processus de sortie impure, je me demande si ceux-ci vont nettoyer la mémoire partagée spécifique au noeud.

20
demandé sur Blklight 2009-12-26 21:28:59

8 réponses

une approche de plus en plus commune dans le calcul haute Performance (HPC) est les programmes MPI/OpenMP hybrides. C'est-à-dire: vous avez N Processus MPI, et chaque processus MPI a M threads. Cette approche correspond bien aux clusters constitués de nœuds multiprocesseurs de mémoire partagée.

le passage à un tel schéma de parallélisation hiérarchique nécessite évidemment des changements plus ou moins invasifs, OTOH s'il est fait correctement, il peut augmenter la performance et l'évolutivité du code en plus de réduire consommation de mémoire pour les données répliquées.

selon L'implémentation MPI, vous pouvez ou non être capable de faire des appels MPI à partir de tous les threads. Ceci est spécifié par required et provided arguments à la fonction MPI_Init_Thread () que vous devez appeler à la place de MPI_Init (). Les valeurs possibles sont:

{ MPI_THREAD_SINGLE}
    Only one thread will execute. 
{ MPI_THREAD_FUNNELED}
    The process may be multi-threaded, but only the main thread will make MPI calls (all MPI calls are ``funneled'' to the main thread). 
{ MPI_THREAD_SERIALIZED}
    The process may be multi-threaded, and multiple threads may make MPI calls, but only one at a time: MPI calls are not made concurrently from two distinct threads (all MPI calls are ``serialized''). 
{ MPI_THREAD_MULTIPLE}
    Multiple threads may call MPI, with no restrictions. 

d'après mon expérience, les implémentations MPI modernes comme Open MPI prennent en charge le plus flexible MPI_THREAD_MULTIPLE. Si vous utilisez des bibliothèques MPI plus anciennes, ou certains architecture, vous pourriez être pire.

bien sûr, vous n'avez pas besoin de faire votre threading avec OpenMP, c'est juste l'option la plus populaire en HPC. Vous pouvez utiliser par exemple la bibliothèque Boost threads, la bibliothèque Intel TBB, ou pthreads ou Windows threads.

8
répondu janneb 2010-01-06 01:07:39

Je n'ai pas travaillé avec MPI, mais si C'est comme les autres bibliothèques IPC que j'ai vu qui cachent si d'autres threads/processus/quoi que ce soit sont sur la même machine ou sur des machines différentes, alors il ne sera pas en mesure de garantir la mémoire partagée. Oui, il pouvait manipuler la mémoire partagée entre deux nœuds sur la même machine, si cette machine à mémoire partagée. Mais essayer de partager la mémoire entre les noeuds sur différentes machines serait très difficile au mieux, en raison des questions complexes de cohérence soulevées. Je m'attends à elle ne doit tout simplement pas être mise en œuvre.

dans la pratique, si vous avez besoin de partager la mémoire entre les noeuds, votre meilleur pari est de le faire en dehors de MPI. je ne pense pas que vous devez utiliser boost.interprocess - la mémoire partagée de style, puisque vous ne décrivez pas une situation où les différents noeuds font des changements fins à la mémoire partagée; il est soit en lecture seule ou partitionnée.

les réponses de John et deus couvrent comment cartographier dans un fichier, ce qui est certainement ce que vous voulez faire pour les 5 Go (giga bit