• Aucun résultat trouvé

0.7 Efficacité de la simulation Monte Carlo

0.7.3 Gain d’efficacité par accélération matérielle : le processeur graphique

Le temps de calcul peut être diminué en utilisant des processeurs cadencés plus rapidement, ou en utilisant la parallélisation des calculs à l’aide de fermes de calcul ou de processeurs graphiques. Ce procédé d’accélération n’est pas une méthode de réduction de variance. Le processeur graphique (GPU) est un matériel informatique initialement créé pour accélérer le calcul graphique, semblable au rendu d’images 3D, affiché en temps réel, des jeux vidéos. La puissance d’un processeur graphique ou central (CPU) peut être déterminée par le flux d’opérations en virgule flottante par seconde (FLOPS). La figure0.19montre la nette tendance à la progression des capacités des GPU au cours de la dernière décennie.

Figure 0.19 – Évolution dans le temps de la puissance de calcul théorique, en simple et double précision, quantifiée en GFLOPS pour des CPU et des GPU [141].

Programmation et architecture d’un GPU

Depuis 2007, la compagnie Nvidia propose l’interface de programmation CUDA pour réaliser des calculs généraux sur GPU à travers le langage C, sans avoir recours au contexte de calcul

graphique tel OpenGL ou DirectX. Une autre interface de programmation est survenue peu de temps après : OpenCL. En plus d’une structure hautement parallèle, les GPU sont maintenant efficaces pour la résolution de problèmes scientifiques qui étaient habituellement effectués avec des processeurs centraux (CPU). Un GPU est constitué de nombreux transistors, tout comme un CPU. Néanmoins, c’est dans les tâches qui lui sont assignées que le GPU se démarque, puisqu’un plus grand nombre de transistors sont utilisés pour les opérations dites arithmétiques et logiques et beaucoup moins dans la gestion et le contrôle des données. Cette différence structurelle va donner naissance à la parallélisation des données en accessibilité concomitante. Les GPU exécutent une instruction unique appliquée sur des données multiples (SIMD).

(a) (b)

Figure 0.20 – Une grappe de traitement graphique d’un GPU : grappe de traitement gra- phique (GPC) (a) composée de multi-processeurs (SM) (b) [141].

Un GPU est constitué de plusieurs grappes de traitement graphique (Graphics Processing Cluster) qui comportent plusieurs multi-processeurs. Sur la figure 0.20, les SFU, de l’anglais special function units, correspondent à des unités dédiées à l’exécution de fonctions intrin- sèques. Les cœurs CUDA en vert sur la figure 0.20 correspondent à des unités arithmétiques et logiques. Les cœurs CUDA d’un même multi-processeur exécutent une tâche (kernel) sur des données parallélisées. Ce parallélisme est exprimé en définissant un nombre judicieux de processus légers requis pour accomplir la tâche. Les processus légers sont ensuite groupés dans des blocs qui définissent, de par leur nombre, une grille. Le GPU exécute une fonction nommée kernel et un kernel est assigné à une grille. Au sein d’un bloc, le warp représente la structure

élémentaire d’un point de vue instructionnel. En effet, il est composé de 32 processus légers qui doivent exécuter la même instruction (SIMD).

Plusieurs niveaux de mémoires sont présents sur la carte graphique et ils varient en tailles, en fonction de la marque et de la génération du produit. Chaque multi-processeur possède un nombre important de registres et une mémoire cache L1 partagée par tous les processus légers d’un bloc. Une mémoire cache L2, partagée avec tous les multi-processeurs, est présente pour le contrôle des données des mémoires caches. Enfin, à l’extérieur du GPU, est présente sur la carte graphique, une mémoire globale qui sert notamment de lien entre la mémoire vive et le GPU. C’est le seul niveau accessible en écriture par l’hôte (le CPU). Trois types d’allocations mémoires peuvent être effectués qui vont être listés par ordre croissant de latence d’accès, puis par ordre décroissant en taille : la mémoire globale, la texture et la mémoire constante qui, elle, est en lecture seule. La mémoire globale est écrite par l’hôte. Les tableaux de mémoire globale peuvent eux-mêmes être liés à la texture. Sur la figure 0.20, les unités LD/ST gèrent le chargement et l’écriture en mémoire globale. La texture offre la capacité de réaliser des interpolations linéaires des valeurs dans ces tableaux multi-dimensionnels (jusqu’à 3D). Il y a quatre étapes universelles de programmation pour réaliser un calcul générique sur un processeur graphique :

- Allouer de la mémoire sur la carte graphique et déplacer les données de l’hôte vers la carte graphique.

- Définir la configuration d’exécution (nombre et taille des blocs). - Lancer les kernels.

- Rapatrier les résultats de la carte graphique vers l’hôte.

Depuis la version 6 de CUDA, les développeurs ont la possibilité d’utiliser la mémoire unifiée pour placer/rapatrier directement en mémoire globale des objets définis directement sur l’hôte.

Usage des GPU pour les simulations Monte Carlo en radiothérapie

Au cours des deux dernières décennies, différents procédés informatique ont été proposés pour accélérer les simulations Monte Carlo. On dénombre parmi eux les grappes de calculs, l’in- fonuagique et les GPU. Les deux premiers nécessitent de lourds investissements financiers. Ils sont onéreux en termes de consommation électrique et de maintenance. Par ailleurs, ils demandent des locaux souvent vastes pour pouvoir stocker les serveurs et les CPU qui, de plus, voient leur puissance plafonner (voir figure 0.19). En revanche, la capacité des GPU est en pleine progression, du fait de leur architecture matérielle, des différentes mémoires acces- sibles et de par le principe d’accès coalescent aux données. De plus, ils sont compacts donc transportables, moins chers que les CPU à l’achat et moins énergivores à puissance de calculs équivalente. Par ailleurs, la parallélisation des processus nécessite moins d’effort de dévelop- pement et de maintenance sur GPU que sur CPU. Ainsi, les GPU représentent une solution

d’avenir pour rendre possible l’usage clinique de calcul de dose par technique Monte Carlo pour les diverses déclinaisons de radiothérapie.

Dans les codes Monte Carlo de transport des particules s’exécutant sur GPU, un processus léger s’occupe de transporter une particule dans la matière. Le port direct d’un code Monte Carlo, qui s’exécute d’ordinaire sur CPU, doit être repensé et adapté à l’architecture des GPU, afin de tirer profit de leur puissance de calcul. De plus, la définition de la taille des blocs et du nombre de processus par blocs joue un rôle sur l’efficacité de la simulation afin de tirer parti au maximum des ressources de la carte (notamment des registres).

Limitations

Divergence des processus légers Du fait de la nature stochastique de ces simulations Monte Carlo, certains processus légers d’un warp devront parfois effectuer des instructions différentes. Le matériel informatique et le compilateur gèrent ceci de deux manières : par prédicat ou par sérialisation. Dans les deux cas, une partie de la puissance de calcul est perdue. Le prédicat engendre des instructions additionnelles en assignant le prédicat vrai ou faux aux processus légers qui doivent respectivement suivre l’instruction ou ne pas la suivre. Aucun processus léger sera inactif et seuls les processus ayant le prédicat vrai pourront écrire leurs résultats. Par sérialisation, le warp est scindé en sous-warp en fonction des valeurs d’embranchement. Chaque sous-warps est lancé l’un après l’autre pour exécuter sa branche ; ils sont ensuite de nouveau réunis. La sérialisation engendre le fait que certains cœurs CUDA sont inactifs pendant le temps d’exécution des sous-warps concurrents. Une partie du travail d’optimisation dans un algorithme sur carte graphique consiste à diminuer cette divergence. Dans le cas de transport Monte Carlo de particules, la divergence est réduite en dédiant un kernel par nature de particule pour avoir les mêmes modes d’interactions [8].

Accès concurrent en écriture Il est probable que certains processus légers aient à écrire des résultats dans la même case mémoire au même instant. Ce phénomène est appelé accès concurrent. Sans sérialisation des processus lors de ces accès, les résultats pourraient être erronés. D’un point de vue technique, l’écriture en mémoire globale doit être réalisée à l’aide d’opérations atomiques réalisant cette sérialisation qui va néanmoins engendrer des pertes d’efficacité.

Précision et performance Les calculs sur un GPU peuvent être réalisés en demi, simple ou double précision en virgule flottante. Réduire la précision augmente la performance [142,143]. Il revient donc au développeur de trouver un compromis entre précision et performance pour optimiser un code. Pour exemple, le module de curiethérapie de GPUMCD allie précision et performance en utilisant la précision simple bien que la double précision puisse être préférée à l’étape de la compilation [143]. Les résultats en simple précision sont similaires à moins de 0.1% comparés à ceux obtenus en double précision. De plus, la proportion des particules

qui finissent leurs parcours dans un voxel différent est inférieure à 0.0121% [143]. La commu- nauté scientifique investigue davantage la capacité de reproductibilité des résultats avec les systèmes exploitant les GPU [144, 145]. Des erreurs peuvent également provenir de matériel défectueux suggérant que des tests d’acceptation rigoureux devraient être effectués sur les nouveaux systèmes basés sur les GPU en exécutant à plusieurs reprises des calculs reproduc- tibles [144]. Ainsi, des tests de reproductibilité pourraient être réalisés par les manufacturiers de GPU, de la même manière qu’elles réalisent des tests de performance lors de la mise sur le marché de nouveaux GPU, de nouveaux pilotes ou de nouvelles architectures (e.g. Volta, Pascal, Maxwell, Kepler, Fermi et Tesla).

0.8

État de l’art des simulations Monte Carlo sur GPU

En 2008, un code Monte Carlo pour les photons a été implémenté pour le domaine de l’op- tique biomédicale [146]. Le but était de porter un code existant de transport de lumière sur GPU [147]. Puis ce projet évolua, en GPU-MCML [148], en s’appuyant sur les développements faits dans le domaine [149–152], notamment pour réduire la divergence et en exploitant la mé- moire partagée et constante [148, 151]. De plus, cet article présenta l’implémentation d’un code multi-GPU dont les gains augmentent linéairement avec le nombre de GPU [148]. Une implémentation du transport des photons sur GPU fut réalisée pour des applications d’imagerie radiographique [149], en portant directement le code PENELOPE [153]. Enfin, gCTD, gDRR, gBMC ont permis respectivement de simuler des distributions de dose tomo- densitométrique, de tomodensitométrie conique en conditions cliniques de traitements et des traitements de curiethérapie haut débit de dose à l’iridium 192 [154–156]. Les premiers codes de calcul Monte Carlo sur GPU qui ont été développés pour les applications en radiothérapie sont GPUMCD [8], gDPM [157,158] et diverses implémentations de la physique électromagnétique de Geant4 [159, 160], avec des améliorations significatives en termes de temps de calcul [8–

13,156–164].

0.8.1 Code de calculs de dose par transport Monte Carlo de photons et