Nous verrons que cette notion d'\textit{occupancy}, si elle conserve du sens, peut toutefois être remise en question en optimisant d'autres aspects permettant d'arriver à une réduction de l'effet des latences, comme le parallélisme d'instructions ou l'augmentation du volume des transactions. En effet, ces techniques, et surtout l'utilisation avisée des différents types de mémoire du GPU permettent d'obtenir des performances élevées, parfois inenvisageables en suivant les prescriptions du constructeur.
-\section{Synthèse des contraintes d'implémentation}
+\section{Contraintes de conception}
Certaines de ces contraintes ont déjà été évoquées rapidement, mais il nous semble important d'en donner ici une présentation synthétique.
\begin{enumerate}
\item \textbf{Contiguïté}.
\item \textbf{Partage des ressources d'un SM}
Le paragraphe sur l'\textit{occupancy} a abordé cet aspect par un exemple. Il faut retenir que chaque SM possède des ressources mémoire (registres, mémoire partagée) que les threads des blocs logiques de la grille de calcul se partagent au cours de l'exécution d'un kernel. L'équilibre entre l'utilisation de ces ressources et le dimensionnement de la grille de calcul relève d'un compromis parfois délicat à trouver pour obtenir les meilleures performances possibles.
\item \textbf{Les latences}. L'exécution des kernels subit l'effet de latences d'origines diverses. Les latences d'accès aux mémoires (voir Table \ref{tab-gpu-memoire}), les latences des différentes instructions arithmétiques ou encore les latences crées par l'inter dépendance d'instructions consécutives. Il est impératif de les prendre en considération et de mettre en \oe uvre des techniques adaptées pour les masquer au mieux.
+\item \textbf{La mise au point}. L'ordonnancement des threads n'est pas prévisible et les quelques outils d'aide à la mise au point (debug) permettent simplement de cibler un thread présélectionné de la cible. Cela ne permet en aucun cas de déceler, par exemple, les conflits de banques provoqués par l'interaction d'au moins deux threads. Un outil de profilage développé par le fabricant fournit des informations importantes sur le nombre de conflits de banques et les origines probables des limitations de performance des kernels d'un programme. Il ne s'appuie cependant que sur un bloc de threads pour en extrapoler les résultats à l'ensemble de la grille.
\end{enumerate}
-L'ensemble de ces aspects rend difficile la conception d'implémentations GPU rapides car rares sont les transcriptions directes d'un code CPU qui ne se heurtent pas sévèrement à l'une ou l'autre des contraintes que l'on vient d'énumérer. Les performances qui en résultent sont alors très en deça de celles attendues, voire inférieures à celles de l'implémentation CPU.
+L'ensemble de ces aspects rend difficile la conception d'implémentations GPU rapides car rares sont les transcriptions directes d'un code CPU qui ne se heurtent pas sévèrement à l'une ou l'autre des contraintes que l'on vient d'énumérer. Les performances qui en résultent sont alors très en deça de celles attendues, voire inférieures à celles de l'implémentation CPU. La mise au point étant par ailleurs très délicate, il nous semble important de proposer des kernels élémentaires dont on peut aisément garantir les résultats par des méthodes de test ne nécessitant pas de devoir implémenter conjointement (et mettre au point) les versions CPU équivalentes des algorithmes concernés.