« Les cartes graphiques/Les processeurs de shaders » : différence entre les versions

m
==Microarchitecture==
 
Outre le jeu d’instruction, la conception interne (aussi appelée microarchitecture) des processeurs de shaders possède quelques particularités idiosyncratiques. Rien de bien déroutant pou qui a déjà étudié les architectures à parallélisme de données, mais quelques rappels ou explications ne peuvent pas faire de mal. Tout ce qu'il faut signaler est que les cartes graphiques sont des architectures massivement parallèles, à savoir qu'elles sont capables de faire un très grand nombre de calculs simultanés, durant le même cycle d'horloge. Il faut dire que chaque vertice ou pixel peut être traité indépendamment des autres, ce qui rend le traitement 3D fortement parallèle. Cela a quelques conséquences sur le nombre de processeurs et d'unités de calcul, mais cela influence aussi la hiérarchie mémoire. L'architecture doit être concue pour pouvoir effectuer u maximum de calculs en parallèle, quitte à simplifier fortement la puissance pour des calculs séquentiels (ceux qu'effectue un processeur). Les processeurs de shaders sont donc relativement simples, sans fioritures tant utiles pour du calculs séquentiels : pas d’exécution dans le désordre, de renommage de registres, et autres. La hiérarchie mémoire doit aussi gérer un grand nombre d'accès mémoire simultanés : qui dit plein d'instructions en parallèle qui travaillent sur des données indépendantes dit aussi plein de données indépendantes à lire ou écrire !
 
Les cartes graphiques sont des architectures massivement parallèles, à savoir qu'elles sont capables de faire un très grand nombre de calculs simultanés, durant le même cycle d'horloge. Il faut dire que chaque vertice ou pixel peut être traité indépendamment des autres, ce qui rend le traitement 3D fortement parallèle. Cela a quelques conséquences sur le nombre de processeurs et d'unités de calcul, ainsi que sur la hiérarchie mémoire. L'architecture doit être conçue pour pouvoir effectuer un maximum de calculs en parallèle, quitte à simplifier fortement la puissance pour des calculs séquentiels (ceux qu'effectue un processeur). Les processeurs de shaders sont donc relativement simples, sans fioritures tant utiles pour du calculs séquentiels : pas d’exécution dans le désordre, de renommage de registres, et autres techniques avancées. La hiérarchie mémoire doit aussi gérer un grand nombre d'accès mémoire simultanés : qui dit plein d'instructions en parallèle qui travaillent sur des données indépendantes dit aussi plein de données indépendantes à lire ou écrire !
 
===Un grand nombre d'unités de calcul SIMD===
 
Même les premières cartes graphiques avaient de nombreux processeurs de ''shaders'' en leur sein. De plus, ces processeurs disposaient de plusieurs unités de calculs séparées, capables de faire des calculs en parallèle. Un bon exemple est le processeur de vertices de la Geforce 6800, illustré ci-dessous. On voit que le processeur contient trois unités de calculs séparées : une unité généraliste de calcul sur les vertices, une unité pour les opérations mathématiques complexes (division, racine carrée, racine carrée inverse, autres) et enfin une unité pour le calcul ''Multiply-And-Add'' (une multiplication suivie d'une addition, opération très courante en 3D). On voit que les unités de calculs sont assez spécialisées, avec une ou plusieurs unités généralistes, secondée par des unités capable de faire des calculs spécialisés.
Ces processeurs disposent le plus souvent d'une flopée d'unités de calcul SIMD, à savoir qu'elles calculent des instructions SIMD complètes, chaque pixel étant traité en parallèle.
 
[[File:GeForce 6800 Vertex processor block.png|centre|vignette|upright=2.0|Processeur de shader (vertex shader) d'une GeForce 6800. On voit clairement que celui-ci contient, outre les traditionnelles unités de calcul et registres temporaires, un "cache" d'instructions, des registres d'entrée et de sortie, ainsi que des registres de constante.]]
 
Cela n'a pas changé avec l'unification des ''shaders'', si ce n'est que les unités de calcul ne sont pas aussi spécialisées que dans l'exemple précédent. De nos jours, les unités de calculs dédiées à des opérations bien précises sont plus rares. On ne trouve plus d'unité spécialisé pour les opérations complexes, comme dans l'exemple précédent, de telles opérations pouvant être émulées par une suite d'opérations plus simples. Au lieu de mettre une unité spécialisée utile pour une opération sur 10/20, autant mettre une unité généraliste pour accélérer les calculs simples et fréquents, quitte à émuler les calculs complexes. De plus, les unités de calculs sont devenues beaucoup plus nombreuses. Les GPU modernes disposent d'une flopée d'unités de calcul SIMD identiques, à savoir qu'elles calculent des instructions SIMD complètes, chaque pixel étant traité en parallèle.
 
[[File:SIMD2.svg|centre|SIMD2vignette|Unités de calculs SIMD.]]
 
===Un grand nombre de processeurs/coeurs===
 
[[File:CPU and GPU.png|vignette|Comparaison du nombre de processeurs et de coeurscœurs entre CPU et GPU.]]
[[File:SIMD2.svg|centre|SIMD2]]
 
Pour profiter au mieux des opportunités de parallélisme, une carte graphique contient de nombreux processeurs, qui eux-mêmemêmes contiennent plusieurs unités de calcul. Vu le grand nombre d'unités de calcul, les autres circuits ne peuvent pas trop prendre de place. En conséquence, les unités de décodage et/ou de contrôle sont relativement simples, peu complexes. Leurs fonctionnalités sont limitées au strict minimum, avec cependant quelques optimisations sur les cartes graphiques récentes. Savoir combien de cœurs contient une carte graphique est cependant compliqué, les services marketing gardant un certain flou sur le sujet. Il n'est pas rare que ceux-ci appellent cœurs ou processeurs de simples unités de calcul, histoire de gonfler les chiffres. Et on peut généraliser à la majorité de la terminologie utilisée par les fabricants, que ce soit pour les termes ''warps processor'', ou autre, qui ne sont pas aisés à interpréter. D'ordinaire, ce qui est appelé processeur de thread sur une carte graphique correspond en réalité à une unité de calcul.
 
<gallery widths=500px heights=300px>
CPU and GPU.png|Comparaison du nombre de processeurs et de coeurs entre CPU et GPU.
Cpu-gpu.svg|Comparaison entre l'architecture d'un processeur généraliste et d'un processeur de shaders.
NVIDIA GPU Accelerator Block Diagram.png|Ce schéma illustre l'architecture d'un GPU en utilisant la terminologie NVIDIA. Comme on le voit, la carte graphique contient plusieurs cœurs de processeur distincts. Chacun d'entre eux contient plusieurs unités de calcul généralistes, appelées processeurs de threads, qui s'occupent de calculs simples (en bleu). D'autres calculs plus complexes sont pris en charge par une unité de calcul spécialisée (en rouge). Ces cœurs sont alimentés en instructions par un gestionnaire d’exécution, le Thread Execution Control Unit, qui répartit les différents shaders sur chaque cœur. Enfin, on voit que chaque cœur a accès à une mémoire locale dédiée, en plus d'une mémoire vidéo partagée entre tous les cœurs.
</gallery>
 
===HiérarchieLa hiérarchie mémoire===
 
La hiérarchie mémoire des GPUs est assez particulière, que ce soit au niveau des caches ou de la mémoire, parfois des registres. On y trouve souvent des caches dédiés aux textures ou aux vertices, et les GPUs récents contiennent aussi des caches L1 et L2 de faible taille.
40 957

modifications