Pourquoi mon solveur parallèle est-il plus lent que mon solveur séquentiel?

14

Je jouais avec PETSc et j'ai remarqué que lorsque j'exécute mon programme avec plus d'un processus via MPI, il semble fonctionner encore plus lentement ! Comment puis-je vérifier ce qui se passe?

Sean Farley
la source
Ne pas poster ceci comme réponse car c'est vraiment un "quoi" plutôt qu'un "comment", mais j'ai eu des problèmes similaires dans le passé qui étaient causés par une section de code protégée par mutex accessible à partir de plusieurs threads. Parfois, vous devez vérifier le verrouillage des ressources partagées en arrière-plan.
David Z

Réponses:

13

Cela peut résulter de facteurs architecturaux :

Si la même bande passante mémoire est disponible pour un ou plusieurs processus, vous ne constaterez quasiment aucune accélération car SpMV et les opérations d'algèbre linéaire associées sont limitées en bande passante mémoire.

Il se peut également que la surcharge de communication vous submerge du calcul local. Par exemple, dans les méthodes itératives linéaires, nous recommandons d'avoir au moins 10 000 inconnues par processus.

ou facteurs numériques :

Les préconditionneurs parallèles sont souvent plus faibles que leurs homologues en série. Par exemple, le bloc Jacobi s'affaiblit plus vous utilisez de blocs. Ainsi, vous devez tenir compte du temps supplémentaire consacré aux itérations linéaires supplémentaires. Les conditions non linéaires en général ne fonctionnent pas de cette façon, donc les itérations de Newton sont souvent constantes.

Matt Knepley
la source
8

Chaque fois que vous essayez de paralléliser un programme, vous devez équilibrer un certain nombre de coûts, mais

  • Le coût d'exécution de chaque calcul
  • Le coût de toute communication entre ces calculs
  • Le coût de la gestion de ces calculs

Si vos calculs sont parallèlement embarrassants, le coût des communications sera très faible (entrée et sortie uniquement) et le coût de gestion devrait être très faible.

Si vous avez des interdépendances entre les calculs, le coût des communications peut augmenter considérablement. Si vous avez un algorithme complexe qui prend un temps différent à terminer pour un calcul donné, la complexité de la gestion augmente alors que vous essayez d'utiliser efficacement les ressources dont vous disposez.

Comme pour toute forme d'optimisation, la clé est de comparer. Regardez comment il fonctionne sans MPI, comment il fonctionne avec MPI et un processus, puis regardez comment il évolue.

Si vous jouez avec CUDA, essayez de lui donner beaucoup plus de données. Un test ici a entraîné une accélération négative. Nous lui avons donné 1000 fois plus de données et la version GP-GPU s'est terminée presque en même temps, tandis que la version fonctionnant sur le processeur principal a pris 1000 fois plus de temps.

Mark Booth
la source
3

Je vous recommande de faire ce qui suit:

  • Faites un profil de l'exécution temporelle de votre code, avec et sans parallélisation. Si vous avez des doutes sur la façon de procéder, nous pouvons vous aider si vous décrivez mieux votre code.

  • Vous pouvez désormais vous concentrer sur les pièces qui s'exécutent plus lentement en parallèle. Vous devez savoir que la communication entre les processus peut être lente. Comme l'ont souligné Mark et Sean, ce n'est pas parce qu'un problème peut être divisé en threads que cela sera efficace. Vous devez approfondir la question. Mais si vous profilez votre code, cela peut vous aider à trouver des bogues existants. Mes deux centimes.

Si vous expliquez ce que vous faites plus en détail, par exemple avec un flux de travail, quelqu'un peut être en mesure de vous donner une meilleure explication.

jbcolmenares
la source
@ketch: vous avez raison. Désolé et merci de l'avoir remarqué. Édité le texte.
jbcolmenares