CPU/GPUCapsule Technique

Rédigé par

CAPSULE TECHNIQUE

CPU/GPU


CPU/GPU, pourquoi faire ?

CPU comme GPU sont adaptés finalement au même usage : exécuter un programme. La différence fondamentale se trouve finalement sur la manière dont le programme est exécuté. Et pour bien comprendre cette différence, il va falloir se pencher sur ce qu’est un programme. Un programme, c’est comme une recette de cuisine. Une recette de cuisine décrit la suite d’actions à effectuer avec des ingrédients pour arriver au plat final. Un programme n’est qu’une suite d’instructions à appliquer sur des données.

Si faire cuire des pâtes consiste à : 

Afficher la page encyclopédique de SEGA consiste à :

Bien évidemment, pour ces deux exemples, chaque action est constituée d’un ensemble de petites actions qui constituent les plus petites actions descriptibles (envoyer le signal électrique via le bon nerf pour bouger le bon muscle de manière adéquate). Ainsi, ce sont ces petites instructions élémentaires qui constituent un programme.

Comment un CPU exécute un programme ? 

L’intérieur d’un CPU.

Quel que soit le nombre de cœurs de votre processeur, chaque cœur fonctionne quasiment de la même manière. Quand un programme est prêt à être exécuté, il est chargé dans la mémoire RAM. La vitesse de fonctionnement d’un CPU étant supérieure à la vitesse de fonctionnement de la RAM, le CPU copie le programme en RAM dans sa propre mémoire : la mémoire cache qui, elle, fonctionne à la vitesse du processeur. Maintenant que tout est prêt, la suite est assez simple : un programme étant constitué d’instructions et des données sur lesquelles appliquer les instructions, on les lit dans la mémoire cache une par une et on les fait exécuter par l’Unité Arithmétique et Logique. L’UAL est la partie la plus fondamentale d’un CPU car c’est elle qui est constituée d’un ensemble de transistors chargés d’appliquer les modifications demandées par chaque instruction.

 

C’est là un travail effectué uniquement par de l’électronique, qui va appliquer un ensemble de portes logiques pour modifier les données, l’instruction permettant de déterminer les portes logiques à appliquer pour transformer les bits comme on le souhaite.

Le GPU a sombré du côté obscur, attiré par la puissance

Et l’on va désormais parler de notre outsider : le GPU. Nous allons évoquer celle de la carte dédiée, qui est la plus connue. Elle est constituée d’un gros paquet de mémoire fonctionnant à grande vitesse, ce qui nous rappelle la mémoire cache du CPU et de beaucoup (vraiment beaucoup) de cœurs de processeurs. Beaucoup … à quel point ? 

Pour cela, comparons un CPU très haut de gamme et un GPU très haut de gamme à tarif équivalent : 800€ (Oui, le tarif est prohibitif, mais ça donne des gros chiffres pour mieux voir la différence !) :

 

CPU GPU
Nom Intel Core i9-9900KS RTX 2080 SUPER Ventus XS OC
Nombre de coeurs 8 3072
Fréquence maximale 5 GHz  1.8 GHz 
Mémoire 16 Mo 8 Go


Naïvement, on serait tenté de se dire qu’un CPU, c’est du passé ! A tarif équivalent nous avons un CPU capable d’effectuer : 8 * 5 milliard d’instructions par seconde soit 40 milliards d’instructions par seconde.

Et pour le GPU : 3 072 * 1.8 milliards d’instructions par seconde soit 5 529.6 milliards d’instructions par seconde.

Un GPU va allouer beaucoup de données dans sa mémoire, et chacun de ses cœurs va exécuter le programme sur un ensemble de données qui lui est attribué. Comme on a beaucoup de cœurs et beaucoup de mémoire, on est capable de faire des “groupes” de cœurs qui vont traiter un “bout” de la mémoire qui leur est dédié, et permettre ainsi au GPU d’exécuter plusieurs programmes simultanément. Très puissant donc, bien plus qu’un CPU.

SAUF QUE, si l’on utilise encore des CPU c’est que le GPU fonctionne d’une manière différente, et que cette puissance brute théorique est rarement complètement exploitable.

Un programme c’est parfois compliqué

Dans un programme, on doit souvent gérer des instructions conditionnelles. Les plus connues sont : pour, tant que, si. Nous allons évoquer seulement l’instruction “si ». Par chance, c’est une expression que nous utilisons dans la vie de tous les jours.

Par exemple : “S’il fait sombre, allume la lumière”. La syntaxe est toujours la même : SI <situation> ALORS <faire quelque chose> SINON <faire autre chose>.  Et que ce soit en français ou au sein des instructions d’un programme, ça fonctionne de la même manière. On va effectuer l’action du SI ou du SINON, mais pas les deux.

Chaque cœur du CPU est totalement indépendant et gère son instruction sur sa donnée, quoi que fassent les autres, il peut donc optimiser son traitement en ne s’intéressant même pas aux instructions qu’il n’a pas à exécuter, il gagne ainsi du temps.


Exemple :

SI la page “https://www.culture-games.com/societes/sega” n’est pas accessible ALORS

SINON

Dans notre exemple, le CPU ne va pas effectuer le même nombre d’instructions dans le SI ou le SINON, ce qui est très souvent le cas, et c’est donc un sacré gain de temps de pouvoir sauter à la prochaine instruction à effectuer.

Ainsi, si la page est accessible, seules deux instructions sur les sept sont exécutées :

Un GPU exécute la même instruction sur un groupe de cœurs en même temps, seules les données sont différentes.

Le même exemple, sur un GPU, devra exécuter les 7 instructions intégralement, car l’ensemble des cœurs ayant des données différentes, il faut que le SI comme le SINON puissent être exécutés sur chacun d’entre eux si les données l’exigent, on ne peut donc pas prendre de raccourci. Certains cœurs doivent donc se désactiver à certains moments pour ne pas exécuter des instructions non conformes à leurs données, alors que d’autres doivent les exécuter.

CPU et GPU, des points forts différents

Schema RTX

Une RTX de NVidia.

Le CPU est très efficace sur des traitements compliqués, avec beaucoup de conditions, et il n’est donc pas étonnant, qu’il soit particulièrement adapté à une application classique ou à un Système d’Exploitation : plein de traitements particuliers avec plein de cas à gérer sur des données diverses. Il est donc extrêmement généraliste, et ses optimisations visent à atteindre une efficacité incroyable. Le seul moyen pour un cœur de CPU de ne pas travailler est de ne pas avoir assez d’instructions qui lui arrivent, sinon il va forcément travailler à 100% de ces capacités sans aucun temps-mort.

Un GPU n’est un monstre de puissance que sur un traitement avec le moins de cas particuliers possible sur un gros ensemble de données. Et devinez quoi : un affichage graphique c’est un ensemble de pixels, de couleurs, sur lesquels on applique exactement le même traitement, donc cela fonctionne plutôt pas mal ! Qu’on ne s’y trompe pas, si le moteur graphique sollicite énormément le GPU, le moteur physique sollicite des circuits dédiés embarqués dans les GPU (PhysX de NVidia par exemple) et encore énormément les CPU, tout comme les IA utilisées dans les jeux qui sont bourrées de conditions.

Atteindre les 100% d’efficacité avec un GPU demande que chaque cœur ait exactement le même nombre d’éléments à traiter, sans aucune prise de décision (condition) à appliquer. Utiliser de manière efficace un GPU demande donc un (très) gros travail de programmation, de découpage et d’optimisation de code. Il y a donc plus où moins de pertes dans la puissance brute disponible au sein d’un GPU, et l’optimisation des jeux va permettre de diminuer le pourcentage de GPU inutilisé à cause d’un trop grand nombre de conditions dans le code qu’il exécute.


Les jeux en Alpha ou en Béta, souvent non optimisés, sont donc particulièrement consommateurs en ressources pour un résultat peu efficace.

CPU + GPU, le plus efficace actuellement

Profiter des points forts de chacune de ces architectures permet d’avoir un niveau d’efficacité global très élevé, et c’est bien là ce qui nous permet d’atteindre une si grosse puissance de calcul : la complémentarité. Bien évidemment, toutes ces explications sont réduites à leurs composants les plus simples pour rester cohérent et abordable.

Il existe tellement d’optimisations au sein des CPU et GPU que la complexité globale est incroyable et permet d’encore accélérer certaines choses, mais les principes décrits dans cet article restent valides.

Il existe des architectures encore différentes telles que le CELL qui a équipé la PS3, destiné initialement à la recherche. 1 coeur de CPU et 8 coeurs de GPU, très peu de mémoire cache, le but était de charger les instructions comme un flux de données continu directement depuis la RAM. Personne n’y connaissait rien à l’époque, et le CELL restera le seul processeur basé sur ce concept, faisant des jeux PS3 des principes de programmations inédits, chapeau bas aux développeurs. L’Itanium d’Intel a une architecture tellement spécifique que seuls certains OS l’acceptent, et l’ensemble des applications qu’il peut faire tourner sont des applications spécifiques.

Et enfin les processeurs quantiques, basés sur des pourcentages de chances d’avoir une valeur sur un bit de données, tout comme les processeurs neuronaux (spécifiques à l’intelligence artificielle) sont encore des paradigmes différents, mais encore expérimentaux.

Pourquoi doit on installer un jeu/un programme ?

Longtemps, la puissance de la console a été de simplement le besoin de mettre le jeu, d’allumer, et de jouer, alors que le PC demandait une installation. Et bien, sur un PC, impossible de savoir à l’avance quels vont être les CPU et GPU présents. Du coup, le jeu va être transformé dans une version spécifique aux instructions que le CPU et le GPU connaissent, pour que ceux-ci puissent l’exécuter, ce que l’on appelle la compilation.

Pour une console, il n’y a qu’un seul CPU et un seul GPU pour tous les modèles, on peut précompiler le jeu et le fournir dans une version déjà prête à être exécutée.

Et sur les consoles récentes, pourquoi doit-on installer un jeu alors ? Tout simplement parce que le temps d’accès au disque dur embarqué est plus court qu’au lecteur de disque, le but étant donc de réduire les temps de chargement au maximum et de mettre un maximum de grosses données (les textures) sur le disque.