Présentation d’un GPU

1.3         Architecture d’un GPU

A ce jour, le constat d’un tel écart entre CPU et GPU a motivé de nombreux développeurs à s’intéresser à ce type de processeurs, afin de leur faire traiter les calculs intensifs et ainsi décharger le CPU de cette tâche.
Au vu de la Figure 5, nous sommes en droit de nous demander, pourquoi il existe un si grand écart de performance entre un CPU multi-cœur et un GPU, qui est basé lui aussi sur une architecture multi-cœur.
Cet écart est du à la philosophie de conception de ces processeurs.

est du à la philosophie de conception de ces processeurs.

1.3.1        Différence de conception par rapport à un CPU

Différence d'architecture entre un CPU et un GPU
Différence d'architecture entre un CPU et un GPU

Un processeur classique est chargé d’exécuter du code de manière séquentielle : chaque instruction est exécutée l’une après l’autre, au fur et à mesure du déroulement du programme. Il est ce que l’on appelle un processeur de type SISD (Single Instruction on Single Data).

Avec l’apparition des Pentium Pro, les processeurs se sont perfectionnés : au lieu d’exécuter les instructions les unes après les autres, il est capable de le réorganiser à la voler de manière à maximiser son flux de calculs et ce, sans impact sur le programme qui reste séquentiel. Ce type de processeur, dit « Out-of-Order », ont permis une augmentation importante des performances des programmes séquentiels à fréquence d’horloge équivalente (mais au détriment d’un plus grand nombre de transistors).

De plus, les CPU disposent d’un grand cache mémoire, ce qui leur permet de diminuer les temps d’accès aux instructions et aux données pour les demandes complexes. Là encore, à fréquence d’horloge équivalente, le volume du cache a un impact direct sur les performances des programmes séquentiels qui font beaucoup d’allers-retours sur les données qu’ils manipulent.

Parallèlement, à partir du Pentium III, de nouveaux jeux d’instruction (SSE)  ont permis l’amélioration des performances en calcul vectoriel. Le calcul vectoriel consiste à appliquer la même opération à tous les éléments d’un vecteur. On parle alors de SIMD (Single Instruction on Multiple Data).

La conception des CPU modernes est donc particulièrement bien adaptée aux programmes séquentiels mais, malgré l’apparition des jeux d’instruction spécialisés, les performances dans les applications multimédia restent faibles.

En effet, ces dernières ne font que peu d’allers-retours sur les données (qui sont lues une fois pour toutes) et la nature très linéaire des algorithmes qu’elles emploient laisse peu de place à l’optimisation à la volée. Ni l’exécution out-of-order, ni la taille importante du cache, n’offre donc de véritable plus-value.

Un GPU est un microprocesseur essentiellement SIMD. Il sacrifie les fonctionnalités complexes du CPU (out-of-order, cache) au profit d’une grande puissance de calcul vectoriel.

Une autre différence notable entre CPU et GPU est le besoin en bande passante mémoire. Traitant de gros volume de données en temps réel, les puces graphiques nécessitent une bande passante 10 fois supérieure à celle d’un CPU.

Figure 4 - Bande Passante mémoire pour un CPU et un GPU
Bande Passante mémoire pour un CPU et un GPU

A la fin 2006, une puce graphique telle que la G80, pouvait supporter une bande passante de 80 Go/sec dans la DRAM principale. A cause des exigences des caches et des modèles de mémoires auxquels ils doivent s’adapter pour satisfaire les exigences du système d’exploitation ainsi que des besoins spécifiques des applications, l’augmentation de la bande passante mémoire des CPU est plus difficile (et moins nécessaire) Avec des modèles mémoires simples les GPU récents peuvent atteindre un débit de 100 Go/s en mémoire, tandis que les CPU ne dépasseront pas les 20 Go/s avant 3 ans.

Comme nous l’avons vu précédemment, la philosophie de conception des GPU a été forcée par une industrie du jeu vidéo en forte croissance. Cette dernière exerce une énorme pression économique sur la capacité d’exécution de calculs intensifs sur des nombres à virgule flottantes, dans le cadre de jeux toujours plus réalistes et novateurs. Pour répondre à ces attentes, les GPU sont devenus de plus en plus flexibles et génériques, au point de disposer, pour la dernière génération, d’architectures MIMD (Multiple Instruction on Multiple Data), architectures qui permettent d’exécuter des jeux d’instructions différents (threads) en parallèle sur un grand nombre de données.

Ces architectures MIMD, par natures plus ouvertes et flexibles que les SIMD, motive les constructeurs de GPU à chercher la meilleure façon d’elargir leurs activités vers de nouveaux secteurs pouvant avoir besoin de leurs processeurs pour des calculs intensifs.

1.3.2        Comparatif SIMD / MIMD

Les architectures parallèles, composées en général d’un grand nombre d’unité de calcul, exploitent le modes de fonctionnement SIMD / MIMD, autorisant l’exécution simultanées de plusieurs parties de code. Ces modes sont référencés dans la taxonomie de Flynn, classifiant les différents types d’architectures des systèmes informatiques parallèles, toujours d’actualité.

Le SIMD, Single Instruction on Multiple Data, est un modèle de calcul parallèle dans lequel chaque unité de calcul (UC) traite simultanément, avec la même instruction, une partie des données qui leur est propre. Chacune de ces unités va ensuite stocker son résultat dans une partie de la mémoire.

Figure 5 - Modèle parallèle Single Instruction on Multiple Data
Modèle parallèle Single Instruction on Multiple Data

Une exécution de code suivant ce modèle peut être synchrone (on attend qu’une partie du code ait été exécuté sur toutes les unités de calcul. On parle alors de SIMD vectoriel, c’est par exemple le cas pour les GPU) ou asynchrone (chaque  unité de calcul travaille indépendamment des autres. On parle alors de SIMD parallèle).

Les instructions SIMD son accessibles dans de nombreux processeurs depuis 1997 : MMX pour Intel, 3D Now ! pour AMD, les jeux d’instructions SSE (jusqu’à SSE4) pour les processeurs de type x86, AltiVec pour Apple, IBM et Motorola.
Ces instructions sont parfaitement adaptées, par exemple, au traitement du signal, particulièrement au traitement de l’image, dans lequel on fait subir à chaque pixel le même traitement, de façon indépendante. Dans ces cas, l’exécution du code est en général bien plus rapide qu’une implémentation classique SISD dans lequel les instructions sont exécutées exclusivement séquentiellement.
Cependant il existe une contrepartie aux processeurs SIMD : leur programmation est souvent malaisée : un algorithme n’est pas forcément exécutable sur une machine SIMD, la gestion des registres est plus complexe, etc.

Le modèle MIMD, Multiple Instruction on Multiple Data, permet d’exécuter des suites d’instructions différentes sur des données différentes, de façon asynchrone et indépendante, et de stocker les résultats dans une même partie de la mémoire.

Figure 6 - Modèle parallèle Multiple Instruction on Multiple Data
Figure 6 - Modèle parallèle Multiple Instruction on Multiple Data

Les machines MIMD sont plutôt destinées au monde professionnel : les Connection Machines 5 (CM-5) de Thinking Machines Corporation en sont un exemple.
On distingue deux types d’accès mémoire dans ce modèle :

–          Mémoire distribuée : chaque unité de calcul possède sa propre partie mémoire et ne peut accéder à celles des autres. Une communication est possible entre processeurs par le biais de messages ou d’appels de procédures RPC, mais nécessite de connecter ces unités  MIMD de façon adéquate, sur le modèle d’une grille.

–          Mémoire partagée : aucune des unités de calcul n’a de mémoire propre mais toutes peuvent accéder à une même mémoire globale. Un changement effectué par une unité dans cette mémoire est donc visible depuis les autres unités. Pour éviter les problèmes de synchronisation, les principes d’exclusion sont utilisés : sémaphores, mutex, etc.

1.3.3        Cas du modèle PRAM

Le modèle PRAM, Parallel Random Access Machine, permet à des processeurs de partager leur mémoire et d’exécuter des algorithmes parallèles. C’est le modèle utilisé par les GPU.

Trois modèles sont distingués en fonction de leurs moyens d’accès à la mémoire, liés aux notions de gathering et scattering :

–          EREW, Exclusive Read Exclusive Write : chaque processeur ne peut lire ou écrire à un endroit mémoire que si aucun autre n’y accède au même moment.

–          CREW, Concurrent Read Exclusive Write : chaque processeur peut lire à n’importe quel endroit de la mémoire, mais plusieurs processeurs ne peuvent écrire simultanément au même endroit.

–          CRCW, Concurrent Read Concurrent Write : chaque processeur peut lire et écrire où il le souhaite en mémoire. On distingue alors trois sous-cas :

  • CRCW commun : si plusieurs processeurs écrivent la même valeur au même endroit, l’opération réussit. Sinon, elle est considérée comme illégale.
  • CRCW arbitraire : si plusieurs processeurs écrivent au même endroit, un des essais réussit, les autres sont avortés.
  • CRCW prioritaire : si deux processeurs écrivent au même endroit, leur rang de priorité détermine le seul qui réussit.

1.3.4        Gestion des données : Rassemblement – Dispersion

Le gathering (rassemblement) et scattering (dispersion) évoqués précédemment désignent la possibilité pour une unité de traitement, de lire, respectivement d’écrire, des données à différents endroits de la mémoire adressés indirectement.
Ces deux opérations sont fondamentales dans tous traitements informatiques.

Figure 7 - Représentation des notions de gather et scatter
Représentation des notions de gather et scatter

On peut synthétiser l’opération Gather, par la notation suivante : v=m[i] ,où m est une structure de donnée stockée en mémoire, i un index, et v une variable de stockage.
De la même manière, on peut représenter l’opération Scatter par la notation suivante : m[i] = v.

7 réflexions sur « Présentation d’un GPU »

  1. je suppose que l’article a déjà quelques mois 😉
    Le marché est tellement dynamique qu’il est presque déjà dépassé sur certains points ^^
    Par exemple tu dit que les gpu embarquent jusqu’à 768mo de ram et 200 processeurs de flux alors que le go de ddr est courant depuis plusieurs années et que les dernières ati comportent pas moins de 1600 processeurs de flux !

    J’ai parcourus rapidement et je trouve aussi que tu fait souvent référence au gpu’s nvidia alors qu’il sont souvent moins efficaces que ceux d’ATI (fanboy inside :p)

  2. J’ai commencé à travailler sur mon article en avril.
    Avec les divers documents trouvés, tous avaient comme référence la Geforce 8800 GTX.
    Comme ordinateur de test, j’ai travaillé avec un portable équipé d’une Quadro FX 570M, et de 256 Mo de mémoire.

    Pour ta référence de GPU, tu fais référence à quel modèle?
    Je ne me rappelle pas avoir voir des cartes « grand publics » équipés de Go de DDR.

    Si tu veux bien me donner toutes les références possibles, je me ferai un plaisir de modifier les chiffres de cet article.

    Pourquoi NVidia plutôt que ATI…
    Par le passé j’ai toujours eu de gros soucis avec mes cartes ATI (drivers essentiellement, surchauffe) et je n’ai jamais eu ce problème avec NVidia. ca c’est pour le côté perso.
    Pour le stage, seul CUDA avait fait l’objet de nombreux retour d’expériences, articles dans la presse spécialisée. J’ai eu le choix : le tout nouveau OpenCL ou CUDA.
    Le projet sur lequel je suis étant de la R&D sur une étude de faisabilité, nous avons joué la sécurité avec CUDA. surtout que le passage de CUDA à OpenCL se ferait sans trop de problèmes, les concepts étant similaires.

    Sinon pour ma conclusion, je parlerai des évolutions avec Fermi, les nouveaux outils de développement….

    Encore merci pour tes remarques

  3. Effectivement, tu as raison, a part les cartes dual gpu (512mb par gpu), il n’y a que les très récentes qui disposent de 1go de ddr… ayant possédé une 7950×2 il y a longtemps il me semblais que le go été devenus le standard sur les cartes haut de gamme.

    Concernant les stream processor, les ati en possèdent généralement beaucoup plus que les nvidia. 1600 sur la très récente hd5780 qui dispose justement d’1go de ddr5, 800 sur l’ancienne génération.
    C’est ce qui les rend généralement plus performante en calcul. Il y a un article d’artiflo à ce propos il me semble (calcul md5).

    Cuda étant plutôt orienté entreprise je comprend ton choix vù le retard d’ati sur ce segment 🙂

  4. Merci pour ton commentaire Florian.

    Dans le cadre de tes articles de sécurité, il était normal que tu parles des GPU 🙂

    Travaillant sur ce sujet depuis quelques mois, j’ai voulu t’apporter un petit coup de main 😉

    Le prochain article sera dédié à CUDA et son fonctionnement.

  5. Super article vraiment !

    Tu saurais me dire où tu as eu la figure sur la pipeline du GPU ? (ou peut-être l’as tu faite toi même?)

  6. Bonsoir

    je n suis pas du tout d’accord avec votre description très succincte des specs d’une silicon graphics des années 90 (ou fin 80).

    par example, IrisGL ,l’ancêtre d OpengL, proposait du raytracing en hard, et une foule d operation 2D ou 3D.

    Les SGI plus récente supportant OpenGL (aprés 93-94) proposent sensiblement les mêmes caractéristiques que les cartes actuels, hormis les pixels shader et qq détails.

    d’ailleur remerciez les tech de chez SGI, car sans eux, point de Nvidia Geforce….
    et oui les GEforce sont principalement des adaptations grands publique des cardset Infinite Reality.

    Laurent

Laisser un commentaire