Quand devrais-je décharger le travail sur un GPU au lieu du CPU?

15

De nouveaux systèmes tels que OpenCL sont en cours de fabrication afin que nous puissions exécuter de plus en plus de code sur nos processeurs graphiques, ce qui est logique, car nous devrions pouvoir utiliser autant de puissance que possible dans nos systèmes.

Cependant, avec tous ces nouveaux systèmes, il semble que les GPU soient meilleurs que les CPU à tous points de vue . Étant donné que les GPU peuvent effectuer des calculs parallèles, les GPU multicœurs semblent en réalité bien meilleurs que les processeurs multicœurs; vous seriez capable de faire de nombreux calculs à la fois et d'améliorer vraiment la vitesse. Existe-t-il encore certains cas où le traitement en série est toujours meilleur, plus rapide et / ou plus efficace que le parallèle?

RétroX
la source
6
Pas vraiment une question de matériel. Devrait être reformulé en "quand est-ce que la programmation des CPU est meilleure que celle des GPU" et est telle est une assez bonne question p.se IMO. Voir la balise GPGPU entre autres sur SO. Mais les questions d'architecture «Quelle technologie utiliser» sont meilleures ici que là-bas.
Kate Gregory
1
@Kate Cet angle semble être très bien couvert dans la question du super utilisateur lié. En le lisant, je suis un peu surpris qu'il n'ait pas migré ici, pour être honnête. Il y a aussi ça sur SO. Je vais rouvrir la question (puisque vous avez raison, les aspects de programmation de celui-ci sont sur le sujet ici). J'espère que nous verrons une réponse qui ne pointe pas seulement sur la couverture (excellente) existante de ce problème.
Adam Lear
1
Pour le point de @ Anna, je pense que les réponses doivent être beaucoup plus sur le moment où un programmeur devrait utiliser le GPU plutôt qu'une discussion purement théorique de la différence entre un GPU et un CPU. J'ai édité le titre pour refléter cela.
2
@RetroX Nous ne pouvons pas fermer les questions en double si elles se trouvent sur des sites différents.
Adam Lear

Réponses:

26

Cependant, avec tous ces nouveaux systèmes, il semble que les GPU soient meilleurs que les CPU à tous points de vue.

Il s'agit d'une mauvaise compréhension fondamentale. Les cœurs GPU actuels sont toujours limités par rapport aux processeurs haut de gamme actuels. Je pense que l'architecture Fermi de NVIDIA est le GPU le plus puissant actuellement disponible. Il n'a que des registres 32 bits pour l'arithmétique des nombres entiers, et moins de capacité de prédiction de branche et d'exécution spéculative qu'un processeur Intel courant. Les puces Intel i7 offrent trois niveaux de mise en cache, les cœurs Fermi n'en ont que deux et chaque cache sur le Fermi est plus petit que le cache correspondant sur l'i7. La communication interprocessus entre les cœurs GPU est assez limitée et vos calculs doivent être structurés pour tenir compte de cette limitation (les cœurs sont groupés en blocs et la communication entre les cœurs d'un bloc est relativement rapide, mais la communication entre les blocs est lente).

Une limitation importante des GPU actuels est que les cœurs doivent tous exécuter le même code. Contrairement aux cœurs de votre processeur, vous ne pouvez pas dire à un cœur GPU d'exécuter votre client de messagerie et à un autre cœur d'exécuter votre serveur Web. Vous donnez au GPU la fonction d'inverser une matrice, et tous les cœurs exécutent cette fonction sur différents bits de données.

Les processeurs du GPU vivent dans un monde isolé. Ils peuvent contrôler l'affichage, mais ils n'ont pas accès au disque, au réseau ou au clavier.

L'accès au système GPU entraîne des frais généraux substantiels. Le GPU a sa propre mémoire, donc vos calculs seront limités à la quantité de mémoire sur la carte GPU. Le transfert de données entre la mémoire GPU et la mémoire principale est relativement coûteux. De manière pragmatique, cela signifie qu'il n'y a aucun avantage à transmettre une poignée de calculs courts du CPU au GPU, car les coûts de configuration et de démontage satureront le temps requis pour effectuer le calcul.

L'essentiel est que les GPU sont utiles lorsque vous avez plusieurs (comme des centaines ou des milliers) de copies d'un long calcul qui peuvent être calculées en parallèle. Les tâches typiques pour lesquelles cela est courant sont le calcul scientifique, l'encodage vidéo et le rendu d'image. Pour une application comme un éditeur de texte, la seule fonction où un GPU peut être utile est de rendre le type à l'écran.

Charles E. Grant
la source
La prise en charge double précision fait partie du Shader Model 5, et AMD / ATI l'a également.
Ben Voigt
@Ben, merci pour la correction. J'ai supprimé la déclaration incorrecte.
Charles E. Grant,
11

Les GPU ne sont pas des processeurs généralistes comme les CPU. Ils se spécialisent dans une chose très spécifique - appliquer le même code à une grande quantité de données - et ils le font très, très bien, bien mieux qu'un CPU. Mais la majorité de la plupart des applications ne consiste pas à appliquer le même code à une grande quantité de données; il s'agit d'une boucle d'événement: attendre l'entrée, lire l'entrée, agir dessus, puis attendre plus d'entrée. C'est un joli processus en série, et les GPU sont nulles en "série".

Lorsque vous avez une grande quantité de données à traiter et que chaque élément peut être traité en parallèle, indépendamment des autres, alors allez-y et envoyez-le au GPU. Mais ne pensez pas à cela comme "le nouveau paradigme" dans lequel tout doit être pressé.

Cette question est étiquetée «optimisation», alors n'oubliez pas de la traiter comme une seule. Appliquez l'optimisation GPU lorsque les tests et le profilage révèlent qu'une optimisation est nécessaire et que la nature de la tâche est telle que l'optimisation GPU peut être appliquée. Sinon, ne vous embêtez pas avec cela, car cela serait une optimisation prématurée ou incorrecte, ce qui cause plus de problèmes qu'elle n'en résout.

Mason Wheeler
la source
8

La réponse simple est qu'un GPU fonctionne mieux lorsque vous devez effectuer un calcul assez petit et assez simple sur chacun d'un très grand nombre d'éléments. Pour accomplir beaucoup de cette façon, le calcul de chaque élément doit être indépendant des calculs pour les autres éléments. S'il y a (normalement) une certaine dépendance entre un élément et un autre, vous devez généralement trouver un moyen de le casser avant de tirer le meilleur parti de l'exécution de ce code sur le GPU. Si la dépendance ne peut pas être brisée du tout ou nécessite trop de travail pour être brisée, le code peut s'exécuter plus rapidement sur le CPU.

La plupart des processeurs actuels prennent également en charge un certain nombre de types d'opérations qu'un GPU actuel ne tente tout simplement pas de prendre en charge (par exemple, la protection de la mémoire pour le multitâche).

En regardant dans une direction légèrement différente, les processeurs ont été (en grande partie) conçus pour être raisonnablement pratiques pour les programmeurs, et les gens du matériel ont fait de leur mieux (et c'est le meilleur!) Pour créer du matériel qui maintient ce modèle pratique pour le programmeur, mais exécute toujours aussi rapidement que possible.

Les GPU viennent dans des directions plutôt opposées: ils sont conçus en grande partie pour être pratiques pour le concepteur de matériel, et des choses comme OpenCL ont tenté de fournir un modèle de programmation aussi raisonnable que possible compte tenu des contraintes du matériel.

L'écriture de code à exécuter sur un GPU prendra généralement plus de temps et d'efforts (donc cela coûtera plus cher) que de faire de même sur le CPU. En tant que tel, cela est principalement logique lorsque / si:

  1. Le problème est si parallèle que vous pouvez vous attendre à un gain important avec un effort minimal, ou
  2. Le gain de vitesse est si important qu'il justifie beaucoup de travail supplémentaire.

Il existe des possibilités évidentes pour chacun - mais un grand nombre d'applications ne sont clairement pas proches de l'une ou l'autre. Je serais assez surpris de voir (par exemple) une application CRUD s'exécuter sur un GPU de sitôt (et si c'est le cas, cela se produira probablement parce que quelqu'un s'est fixé cet objectif précis à l'esprit, pas nécessairement quelque chose approchant un optimal rapport coût / bénéfice).

La réalité est que pour de nombreuses applications (je suis tenté de dire "la plupart"), un CPU typique est beaucoup plus que suffisamment rapide, et la commodité de la programmation (conduisant à des choses comme le développement plus facile de nouvelles fonctionnalités) est beaucoup plus importante que vitesse d'exécution.

Jerry Coffin
la source
3

vous seriez en mesure de faire de nombreux calculs à la fois et d'améliorer vraiment la vitesse.

améliorer la vitesse? et alors? Tout au long de l'année dernière, je ne me souviens qu'une ou deux fois quand c'était nécessaire. La plupart du temps , je suis invité à modifier ou à la logique fixe, pour régler une source de données, pour améliorer l' interaction de l' utilisateur , etc. , etc. La seule vitesse clients étaient intéressés par ces cas était vitesse de faire un changement. "Veuillez publier une nouvelle fonctionnalité dans un mois, ou mieux encore - dans deux semaines".

Ne vous méprenez pas - en tant que codeur, j'aime bien serrer les tics CPU. C'est juste que cet art n'est généralement pas très demandé.

Existe-t-il encore certains cas où le traitement en série est toujours meilleur, plus rapide et / ou plus efficace que le parallèle?

Je dirais qu'il y a beaucoup de cas. Le traitement en série est plus simple que parallèle, ce qui le rend plus efficace dans tous les cas où la vitesse n'est pas une exigence critique. Le traitement en série permet une mise en œuvre plus facile d'une logique et d'une interface utilisateur compliquées, il est plus facile de spécifier et de tester, de maintenir et de modifier.

En règle générale, le traitement en série permet une expression plus claire de l'intention du programmeur et une lecture plus facile du code. Je dirais que cela économise la ressource la plus précieuse et la plus rare - le cerveau du programmeur.

moucheron
la source
2

Les processeurs sont encore plus polyvalents. Par exemple, les GPU sont plus efficaces que les CPU en simple précision, mais pas en double précision. Il y a beaucoup plus de bibliothèques pour les CPU que pour les GPU.

quant_dev
la source
3
Pouvez-vous entrer un peu plus dans les détails? Vous avez fourni trois déclarations sans aucune information ni explication quant à leur véracité.
Eh bien, le manque de calculs efficaces en double précision est de notoriété
publique
@quant: Vos informations sont périmées depuis au moins 2 ans: 544 GigaFLOPS est beaucoup plus rapide que n'importe quel processeur traditionnel.
Ben Voigt du
@Ben Je ne vois pas où votre lien mentionne les performances de double précision.
quant_dev
@quant: awurl.com/Tt7LAX8lH
Ben Voigt
2

La règle simple est que si ce que vous faites peut être formulé en termes de constructions à partir d'algèbre linéaire et est critique en temps, faites-le sur le GPU sinon utilisez le CPU.

Les GPU ne sont pas comme un grand nombre de CPU, ils ont des caractéristiques de performances très différentes.

dan_waterworth
la source
Si c'est "temps critique", vous n'avez probablement pas le temps de reconfigurer le GPU pour un shader de calcul et de télécharger les données. Ce sont les gros problèmes qui en profitent le plus.
Ben Voigt
@Ben, je pense que nous avons différentes définitions de "temps critique", ce que je veux dire, c'est que le calcul est sur le chemin critique pendant une durée significative.
dan_waterworth
1

Si vous avez besoin de chiffres bruts, les GPU sont le chemin à parcourir. Cependant, toutes ces ALU signifient qu'il y a moins de transistors dédiés au contrôle du circuit (branchement). Donc, si vous avez besoin d'écrire quelque chose qui nécessite beaucoup de flux de contrôle complexes, beaucoup de conditions, etc., un processeur sera plus rapide.

Alex
la source