• Aucun résultat trouvé

2.2 Simulation de la propagation acoustique par FDTD et implémentation ISL 19

2.2.10 Parallélisation du code

30 40 50 λ/dx T/dt

Figure 2.6  Domaine choisi pour stabiliser le calcul dans le code ITM (domaine grisé). Dans ce cas, la simulation est 2D et le schéma spatial est centré d'ordre 4. enn cdt/dx > 1, cdt/dx > 1/2ou cdt/dx > 1/3pour les simulations respectivement 1D, 2D ou 3D. Ces conditions sont résumées en gure 2.6 pour une simulation 2D utilisant le schéma spatial d'ordre 4. Compte tenu du schéma spatial de faible ordre utilisé dans le code ITM, la condition T/dt > 10 est toujours remplie car moins restrictive que la condition sur le nombre de Courant-Friedrichs-Lewy. Ceci est également visible en gure 2.6. Les schémas de faible ordre, nécessitant moins de points, sont moins stables mais présentent l'avantage de faciliter l'implémentation des conditions aux limites.

Dans les simulations présentées, aucun ltre numérique n'est appliqué car ils n'ont pas été nécessaires pour stabiliser les calculs.

2.2.10 Parallélisation du code

Les simulations FDTD sont extrêmement lourdes et nécessitent généralement des ressources en terme de temps de calcul et d'utilisation mémoire non négligeables. Ces besoins augmentent lorsque les signaux acoustiques propagés contiennent des compo-santes haute fréquence, lorsque le domaine de calcul est grand, ou encore lorsque la simulation est 3D. Des temps de calcul de l'ordre de l'heure sont courants (Cotté 2008) et peuvent rapidement atteindre des durées inenvisageables. L'autre limitation porte sur l'espace de mémoire vive nécessaire aux calculs. Il est courant d'atteindre le gigaoctet ce qui peut rendre certaines simulations impossible même à démarrer.

Diérentes stratégies existent pour contourner ces limitations. L'approche la plus ecace est l'adaptation du code de calcul pour utiliser les capacités de l'architecture matérielle sur lequel il est exécuté. On peut citer la vectorisation, qui consiste à adapter le code pour utiliser les capacités de calcul sur vecteurs et matrices de certains processeurs. Ce type de processeur ne semble néanmoins plus être la tendance des supercalculateurs.

Une autre approche est le GPGPU (General-purpose Processing on Graphics Processing Units) qui consiste en l'utilisation des cartes graphiques pour des calculs génériques. Les cartes graphiques ont été développées pour être très performantes et grand-public, ce qui rend leur prix abordable par rapport à d'autres architectures ayant les mêmes capacités de calcul. L'utilisation des cartes graphiques pour le calcul numérique permet un calcul souvent beaucoup plus rapide que le code initial. Cette approche est cependant encore récente et les diérents standards proposés sont limités à une architecture don-née (par exemple, CUDA—ne fonctionne que sur les cartes graphiques NVIDIA®et ATI Stream—que sur les cartes AMD®) ou ne sont pas totalement supportés (par exemple, OpenCL ne permet pas d'utiliser toutes les capacités de ces cartes graphiques). En-n, la parallélisation du code pour utiliser les capacités des machines parallèles est une approche très populaire. De nombreuses architectures parallèles existent et plusieurs standards sont communément supportés. La plupart des supercalculateurs sont consti-tués de machines parallèles.

La parallélisation consiste à utiliser simultanément (de manière parallèle) plusieurs processeurs sur une architecture de calcul. Sans parallélisation, le code est scalaire et n'exploite les capacités que d'un seul processeur, alors qu'aujourd'hui la plupart des nouveaux ordinateurs ont au moins 4 ou 8 processeurs. Les codes de calcul par FDTD se prêtent particulièrement à la parallélisation car les opérations à eectuer dans les boucles de calcul ne dépendent pas les unes des autres et peuvent donc être eectuées simultanément sur les processeurs disponibles.

Lorsque l'ensemble des processeurs partagent une mémoire commune, comme c'est le cas sur les ordinateurs de bureau (architecture à mémoire partagée), le standard permettant l'utilisation de plusieurs processeurs est le standard OpenMP (pour Open Multi Processing). Ce standard est implémenté sur de nombreux compilateurs et l'accès à la parallélisation se fait simplement dans le code en ajoutant des directives au niveau des boucles de calcul parallélisables (Hermanns 2002). L'eort d'implémentation est léger et rentable, et seuls quelques aspects doivent être surveillés comme l'accès simultané en lecture/écriture sur un chier ou l'utilisation de variables propres à chaque processus. Le gain en temps de calcul maximal est proportionnel au nombre de processeurs utilisés (temps de calcul divisé par 4 si 4 processeurs sont utilisés par exemple). Cependant dans les codes de calcul, certaines parties sont impossible à paralléliser et restent scalaires. De plus le compilateur génère des instructions supplémentaires pour l'initialisation de la parallélisation. Ce maximum n'est donc généralement pas atteint et il est courant d'avoir un rendement de l'ordre de 75%, où le rendement est déni par le gain de temps eectif divisé par le gain de temps maximal théorique. Une illustration de la parallélisation par OpenMP est donnée en gure 2.7.

Lorsque la mémoire n'est pas partagée entre les processeurs le standard OpenMP n'est pas applicable. Cependant il est également possible de paralléliser un programme sur les architectures à mémoire distribuée par le standard MPI (pour Message Passing Interface). Ce standard fournit des fonctions permettant le passage de données entre les diérents noeuds du système (chaque noeud ayant sa propre mémoire) (Gropp et al. 1999, Chergui et al. 2011). Ainsi pour exécuter un programme parallèle sur ce type d'ar-chitecture, il faut décomposer le domaine de calcul en sous-domaines à distribuer aux noeuds, laisser chaque noeud calculer son propre sous-domaine, et transférer la mémoire d'un noeud à l'autre lorsqu'une donnée externe à sa propre mémoire est nécessaire. Pour

(a) (b)

(c) (d)

Figure 2.7  Illustration du découpage du domaine de calcul pour les diérentes parallélisations. Les engrenages représentent les processeurs et les èches les transferts

des frontières par le réseau. (a) scalaire, (b) OpenMP, (c) MPI, (d) OpenMP+MPI. les applications de type FDTD, ce sont les données aux frontières qui sont généralement nécessaires et échangées entre les noeuds. Ce standard présente plusieurs avantages dont le principal est la division du domaine, ce qui diminue la mémoire vive nécessaire pour un noeud et permet d'envisager des calculs nécessitant énormément de mémoire vive. Le nombre de noeuds utilisables n'est pas limité et peut être augmenté facilement (en ajoutant un noeud au réseau par exemple) alors qu'il est impossible d'ajouter un pro-cesseur à une architecture à mémoire partagée. Cependant les eorts de programmation pour implémenter un code utilisant MPI sont importants (en particulier comparés aux eorts pour utiliser OpenMP), et de nombreux aspects critiques doivent êtres soigneuse-ment implésoigneuse-mentés, comme l'accès à un chier sur le disque, le découpage du domaine de calcul, ou les passages de frontières entre les noeuds. Un environnement logiciel adapté, comme le système de gestion de processus Oracle Grid Engine (anciennement Sun Grid Engine), est également nécessaire. L'ecacité de la parallélisation est généralement li-mitée par la bande passante du réseau sur lequel circulent les données entre les noeuds. Une illustration de la parallélisation par MPI est donnée en gure 2.7.

Au sein d'un noeud de calcul, il peut y avoir plusieurs processeurs qui travaillent sur une mémoire partagée. Le standard MPI ne permet pas d'eectuer simplement un traitement diérent selon le type de mémoire existant, et l'avantage potentiel du partage de mémoire entre ces diérents processeurs ne peut pas être pris en compte. Ainsi il existe une dernière approche, la parallélisation hybride en OpenMP et MPI. Ce type de parallélisation consiste en l'utilisation du standard MPI entre les diérents noeuds et du standard OpenMP au sein d'un noeud (Lavallee et Wautelet 2012). Cela permet

de cumuler les avantages des deux types de parallélisation et d'optimiser le calcul pour l'architecture présente. De plus, la tendance des noeuds de calcul est à l'augmentation du nombre de processeurs, ce qui justie l'utilisation de la parallélisation hybride. Cela se fait tout de même au prix de la complexication du code qui prend donc deux niveaux de parallélisation. Une illustration de la parallélisation hybride est donnée en gure 2.7. Implémentation ISL

Le code ITM était scalaire en début de thèse. An d'améliorer les temps de calcul le standard OpenMP a été implémenté. Enn la mise à disposition d'un cluster de calcul ainsi que les forts besoins numériques pour les simulations des chapitres 4 à 6 ont motivé l'implémentation du standard MPI. Le code ITM est maintenant totalement hybride OpenMP et MPI.

An de donner une idée des temps de calculs et gains obtenus par l'implémentation de la parallélisation, des données complémentaires sont proposées en annexe C.