Carte graphique et programmes

Le problème exposé dans ce sujet a été résolu.

Bonjour,

ce soir, je suis bien inspiré pour mes questions. Je me demandais ce qu'il se passait quand un programme décidait qu'il devait envoyer des choses à la carte graphique. Enfin, plutôt quand le programmeur décidait que le programme devait le faire, du point de vue bas-niveau. Par exemple, si je suis seul dans ma cave, un certain nombre de jours, je pourrais tout à coup me dire que je ferais une GUI en assembleur. Eh bien, que dois-je faire ? Je dois appeler des fonctions système qui parleront aux pilotes ? Et ces pilotes, ce sont des programmes en langage machine, lus par le CPU. Que font leurs instructions pour que le CPU envoie de choses à faire à la carte graphique ? Je suis peut-être orienté dans la mauvaise direction, mais par ma place d'ignorant, j'ignore ce que je ne sais pas. Merci !

Je dois appeler des fonctions système qui parleront aux pilotes ? Et ces pilotes, ce sont des programmes en langage machine, lus par le CPU. Que font leurs instructions pour que le CPU envoie de choses à faire à la carte graphique ?

Globalement il faut voir dans ces cas là comme une communication entre périphériques via un protocole. Tu n'as pas de mnémonique précise et générique pour faire ce que tu demandes. En réalité le code assembleur va juste faire des transferts mémoires pour effectuer un transfert de données vers le GPU.

Cela fonctionne de la même manière pour si tu veux faire un envoi de données par Ethernet, PCI, I2C, SPI, SATA, etc. Tu as des registres du processeur (à une adresse précise de la mémoire du processeur) pour recevoir et émettre des informations par un protocole défini. Cela est géré derrière matériellement, tu n'en sais pas beaucoup plus en général.

Ensuite le GPU va recevoir cette information, l'interpréter et faire ce qui est demandé avant de renvoyer les résultats. Après en général on ne sait pas trop ce qui se passe dans le GPU dans ce cadre là. C'est souvent caché, les pilotes sont rarement libres tout comme les firmwares. Et les GPU sont des composants très complexes.

Là j'ai décrit le cas où la mémoire du GPU était disjointe du CPU. Ce n'est pas toujours le cas (je crois notamment dans les puces Tegra de nVidia). Ce cas là est plus complexe, moins courant et peu documenté.

+0 -0

Je suis également un ignorant à ce niveau là, mais si j'ai bien compris les explications de Renault c'est un échange d'informations entre le processeur et la carte graphique via leur mémoire respective (puisque le processeur contient lui-même une petite quantité de mémoire).

Si j'ai bien compris, le CPU place des informations dans la mémoire (la RAM ?) là où le GPU écoute ?

Non. Le GPU est, en général, un composant disjoint du CPU. Ils communiquent entre eux via un protocole électronique et non uniquement logique. Cela se fait via des adresses spécifiques. Le processeur a des adresses dans son espace mémoire correspondant aux entrées/sorties pour communiquer avec l'extérieur. Ce sont des registres spécialisées non représentés dans un langage tel que l'assembleur (ce sont pour eux des adresses mémoires uniquement). Ces zones ne font donc pas parties de la RAM.

La carte graphique a de son côté également de telles zones mémoires pour communiquer avec l'extérieur. Suivant qui écrit dans sa zone dédiée, une communication électronique s’établira entre les deux composants permettant d'échanger des données. Cela fonctionne de la même façon pour tout composant n'ayant pas accès à la RAM du CPU directement.

+0 -0

La RAM du CPU ? La RAM n'est-elle pas disjointe du CPU ? Et je n'ai pas vraiment compris précisément cette explication. Peut-être un exemple simplifié m'aiderait, si toutefois il est possible d'en donner (je sais que le sujet est délicat).

+0 -0

Chaque ordinateur possède un plan d'adressage qui permet de dire quelle adresse correspondra à quel périphérique. Souvent une très grande partie de cet adressage relie le CPU à la RAM, mais une petite partie de ces adresses sont réservées pour la communication avec les périphériques externes.

C'est très facile de trouver un exemple avec les ports parallèle et série des vieilles machines avec un BIOS (COM1, COM2, LPT1, …) qui possèdent des adresses en dur (fixées par la norme BIOS de mémoire) qui permettent d'accéder directement à ces périphériques.

C'est également valable pour l'ISA, et sans doute aussi pour les cartes graphiques (PCIE x16 le plus souvent pour les cartes modernes).

P.S. : si tu veux t'amuser avec une carte graphique je te conseille de regarder du côté d'OpenCL au lieu de partir sur de l'assembleur. C'est pas très haut niveau (du C) mais ça permet de très bien visualiser les transferts entre le CPU et le GPU que tu dois expliciter dans ton code.

+0 -0

En fait, ce que j'essaie de comprendre, c'est qu'est-ce qu'il se passe dans les programmes. Dites-moi si je me trompe, mais si je fais une GUI, je dois appeler des fonctions systèmes qui appellent les drivers. Mais ces drivers sont bien exécutés par le CPU, n'est-ce pas ? Alors si j'ai vaguement compris, ces drivers vont dire au CPU d'écrire quelque part dans la mémoire (je n'ai toujours pas compris où) et le GPU va s'en rendre compte et faire ce qu'il faut, c'est ça ?

J'ai trouvé ça : coucou, je suis un lien. Ça confirme ce que je pensais. Au final, tout passe par le CPU, et les drivers sont une sorte de bibliothèque de fonctions que je peux appeler dans mon programme, et qui écrivent dans les bonnes zones de mémoires (dans une zone réservée de la RAM ?). J'y suis ? (Certains navigateurs vont transformer le caractère ',' du lien en "%2C", ce qui donne une page qui n'existe pas. Il n'y a qu'à remplacer "%2C" par ",")

Merci beaucoup !

+0 -0

Pour simplifier mes explications, je prend en exemple le SoC (System on Chip) AM3354 de Texas Instruments (car documentation complète fournie et pas trop bourrée de fautes). Le SoC contient à la fois un CPU à base d'ARM et un GPU à base de PowerVR, le tout interconnecté en interne de la puce.

Alors c'est légèrement différent pour un CPU x86 et une carte graphique externe car ce n'est pas un bus interne, mais une liaison en PCI express (que j'abrège PCIe) dans ce cas. Mais le principe de fonctionnement reste le même.

Concernant le AM3354, la page TI est ici : http://www.ti.com/product/AM3354/description
Le lien vers la datasheet (pas trop d'intérêt dans notre cas) : http://www.ti.com/lit/ds/symlink/am3354.pdf
Le lien vers le Technical Reference Manual (ou Programmer's Manual) : http://www.ti.com/lit/ug/spruh73m/spruh73m.pdf

Tout CPU dispose d'un plan mémoire qui définit les adresses mémoires réservées. Celles-ci sont en partie programmée en dur par le fabricant, il faut donc se référé à la documentation pour la connaître.

Pour l'AM3354, la memory map c'est page 176 et ça fait 10 pages :)
Pour s'y retrouver il faut avoir le diagramme d'architecture globable :

Image utilisateur

Toutes les fonctions sont adressables via des adresses dédiées. Tu veux utiliser de l'I2C ? Dans ce cas pour l'I2C1 (il y a 3 ports I2C sur le SoC), les adresses dédiées sont en page 180 du TRM :

Image utilisateur

TI étant sympa ils mettent un lien pour aller directement sur le détail des registres correspondants (page 4494, oui !). Comme il y a plusieurs ports I2C mais que leur utilisation est plus ou moins similaire, c'est un offset d'adresse qui est utilisé et non pas les adresses en dur.

Imagine que ce n'est que de l'I2C, un truc assez simple, et qu'il faut donc naviguer dans la doc et se taper une bonne dizaine de pages pour avoir le détail des registres, et il faut ensuite lire toute la partie pour savoir comment ça fonctionne exactement, car il y a souvent des petites subtilités propres aux différents fabricants.

Concernant la partie GPU, dans notre exemple, il est nommé Graphics Accelerator (SGX) dans le TRM, chapitre 5, page 443.

Ce schéma te donne l'intégration du GPU au sein du SoC (cf diagramme d'architecture) :

Image utilisateur

Attention ! L3 et L4 ne correspondent pas à des mémoires caches comme sur un CPU, ce sont les bus d'interconnexion interne au SoC. Comme nous l'explique le chapitre 10 (Interconnects) du TRM :

  • The L3 high-performance interconnect is based on a Network-On-Chip (NoC) interconnect infrastructure. The NoC uses an internal packet-based protocol for forward (read command, write command with data payload) and backward (read response with data payload, write response) transactions. All exposed interfaces of this NoC interconnect, both for Targets and Initiators; comply with the OCPIP2.2 reference standard.

  • The L4 interconnect is a non-blocking peripheral interconnect that provides low latency access to a large number of low bandwidth, physically dispersed target cores. The L4 can handle incoming traffic from up to four initiators and can distribute those communication requests to and collect related responses from up to 63 targets.

Bref, notre GPU est connecté sur le bus L3 qui se veut être un Network-on-chip, imagine un réseau ethernet qui relie les périphériques, mais à l'intérieur de la puce ;)

Image utilisateur

En jaune, notre GPU, en rouge le CPU, le reste ce sont des périphériques. En haut ports Initiator et en bas les Target. Bon on va pas s'étendre dessus :)

Revenons à notre GPU et à notre memory map pour voir son adressage :

Image utilisateur

Si cherche dans le TRM, il n'y a pas plus d'infos sur le GPU, on reste un peu bloqué, car on a bien l'intégration et la plage d'adresse pour le GPU mais pas le détail de ses registres. TI a enlever le détail, je ne sais pas trop pour quelles raisons, mais on peut supposer que sur cet autre SoC qui utilise aussi le SGX530, on a les même registres : http://www.ti.com/lit/ug/sprugx8c/sprugx8c.pdf (page 186)

Image utilisateur

Le problème c'est qu'il faudrait avoir la doc du SGX530 qui est fait par Imagination Technologie, sauf que cette doc n'est pas gratuite.

Mais c'est suffisant pour reprendre les explications de ton lien Tom's hardware sur le GPU Radeon. Les deux puces vont partager un espace mémoire commun. La carte graphique dispose d'un petit processeur dédié à la lecture et l'exécution des commandes envoyées par le CPU. Les (CPU et GPU) communiquent au travers d'un ring buffer (c'est ce qu'explique ton article), donc par exemple ton CPU va exécuter du code pour le GPU (fait tel traitement) en envoyant la commande dans le ring buffer, le GPU va lire la commande et l'exécuter, en activant les fonctions dédiées.

Cet article détaille tout ça : https://traxnet.wordpress.com/2011/07/18/understanding-modern-gpus-2/

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte