C’est une question générale sur un sujet que j’ai trouvé intéressant en tant que joueur: les goulots d’étranglement des CPU / GPU et la programmation. Si je ne me trompe pas, j'ai fini par comprendre que le processeur et le processeur graphique calculent des données, mais que l'un est meilleur dans certains calculs que l'autre en raison de la différence d'architecture. Par exemple, le cracking hachage ou l'exploration de crypto-monnaie semble beaucoup plus efficace sur les GPU que sur les CPU.
Je me suis donc demandé: avoir un GPU à 100% de charge alors que le processeur est à 50% (par exemple) est inévitable?
Ou plus précisément: certains calculs normalement effectués par le processeur graphique peuvent-ils être effectués par le processeur si le premier est à 100% de charge, de sorte que les deux atteignent une charge de 100%?
J'ai cherché un peu sur le sujet, mais je suis revenu les mains vides. Je pense et espère que cela a sa place dans cette sous-section et que je suis ouvert à toute documentation ou conférence que vous pourriez me donner!
la source
NO-OP
s en même temps, ce qui entraînera une charge de 100% pour les deux.Réponses:
Théoriquement oui, mais dans la pratique, cela en vaut rarement la peine.
Les processeurs et les GPU sont complets , donc tout algorithme pouvant être calculé par l’un peut également être calculé par l’autre. La question est de savoir à quelle vitesse et quelle commodité.
Bien que le processeur graphique excelle à effectuer les mêmes calculs simples sur de nombreux points de données d'un grand ensemble de données, la CPU est meilleure avec des algorithmes plus complexes comportant de nombreux ramifications. Avec la plupart des problèmes, la différence de performances entre les implémentations de processeur et de processeur graphique est énorme. Cela signifie que l’utilisation de l’un pour prendre le travail de l’autre en décrochage n’entraînerait pas une augmentation notable des performances.
Cependant, le prix à payer pour cela est que vous devez tout programmer deux fois, une fois pour le processeur et une fois pour le GPU. Cela représente plus de deux fois plus de travail, car vous devrez également implémenter la logique de commutation et de synchronisation. Cette logique est extrêmement difficile à tester, car son comportement dépend de la charge actuelle. Attendez-vous à voir très obscur et impossible de reproduire les bugs de cette cascade.
la source
Ce n'est pas lié à la programmation de jeux. Certains codes scientifiques peuvent également utiliser à la fois le processeur graphique et le processeur.
Avec une programmation soigneuse et pénible, par exemple en utilisant OpenCL ou CUDA , vous pouvez charger votre processeur graphique et votre processeur à près de 100%. Très probablement, vous aurez besoin d'écrire différents morceaux de code pour le GPU (appelé code "noyau") et pour le CPU, ainsi que du code collant ennuyeux (notamment pour envoyer dans le GPU le code du noyau compilé).
Cependant, le code serait complexe et vous aurez probablement besoin de l'adapter au matériel sur lequel vous travaillez, en particulier parce que la transmission de données entre GPU et CPU est coûteuse.
En savoir plus sur l' informatique hétérogène .
Voir aussi OpenACC , pris en charge par les versions récentes de GCC (par exemple, GCC 6 en juin 2016).
la source
Du point de vue des supercalculateurs, il est préférable de ne pas penser en pourcentage de la charge CPU / GPU mais de déterminer le nombre d'opérations nécessaires à votre problème, puis de le comparer aux performances maximales du système.
Si vous obtenez une utilisation du processeur à 100%, cela ne signifie pas nécessairement que vous obtenez toutes les performances du système. Les processeurs peuvent souvent faire plusieurs choses différentes en même temps, par exemple une division et une addition. Si vous pouvez commencer la division plus tôt, l’ajout risque de chevaucher celle-ci. Le processeur de votre ordinateur de bureau a très probablement une unité en panne qui réorganisera les instructions afin de tirer parti de tels chevauchements. Ou si vous avez le programme suivant:
Un processeur en réorganisation essaiera de calculer les trois expressions en même temps , puis jettera le résultat de l'une d'entre elles. Cela le rend plus rapide en général. Si vous avez un bloqueur dans votre programme et que vous ne pouvez pas réorganiser, vous utilisez moins de voies dans la CPU, mais il affichera probablement encore 100%.
Ensuite, vous avez des fonctions SIMD dans les CPU qui sont des opérations vectorielles. Cela ressemble à GPGPU-light en ce sens que vous n’avez généralement que quatre ou huit opérations à la fois, les GPU en ont 32 ou 64. Vous devez néanmoins l’utiliser pour créer les FLOPS.
Des choses comme un faux partage peuvent engendrer des coûts de synchronisation élevés qui apparaissent généralement sous la forme d'une charge de noyau sous Linux. La CPU est complètement utilisée mais vous n’avez pas beaucoup de débit utile.
J'ai fait de la programmation sur une machine IBM Blue Gene / Q. Il comporte de nombreux niveaux de hiérarchie ( schéma de Blue Gene / L obsolète ) et est donc difficile à programmer efficacement. Vous devrez utiliser la hiérarchie complète allant de SIMD à SMT (Intel appelle cet HyperThreading) pour obtenir des performances optimales.
Et puis le réseau vous limite souvent. Par conséquent, il s'avère que le temps (de l'horloge murale) est plus rapide pour calculer des éléments sur plusieurs processeurs en même temps au lieu de les communiquer via le réseau. Cela mettra plus de charge sur les processeurs et accélérera l'exécution du programme. Toutefois, le débit réel du programme n’est pas aussi bon qu’il semble en ce qui concerne les chiffres bruts.
Si vous ajoutez des GPU au mélange, il deviendra encore plus difficile d'orchestrer tout cela pour générer des performances. Ce sera l’une des choses que je commencerai à faire dans ma thèse de maîtrise sur le QCD du réseau dans quelques mois.
la source
Vous voudrez peut-être consulter le moteur de navigation Servo en cours de développement chez Mozilla Research, et plus particulièrement son Web Render (vidéo) .
Bien que déplacer dynamiquement une tâche d'un processeur à un processeur graphique puisse s'avérer peu pratique, comme mentionné dans d'autres réponses (notamment @ Philip's), il peut être pratique d'étudier à l'avance la charge de processeur / GPU sur des charges de travail typiques et de passer de certaines tâches à des tâches généralement moins chargées. une.
Dans le cas de Web Render, la nouveauté est que, traditionnellement, les navigateurs effectuent l'essentiel de leur rendu sur le processeur (le processeur est utilisé pour calculer les objets à afficher, les endroits à couper, etc.). Le GPU est normalement plus performant ... sauf que toutes les utilisations ne sont pas triviales à mettre en oeuvre (suppression partielle, ombres, ... et texte).
Une version initiale de Web Render s’est avérée très efficace pour l’augmentation des performances, mais n’a pas tenté de résoudre le problème du rendu du texte (et comportait quelques autres limitations). Mozilla Research travaille actuellement sur une seconde version qui devrait avoir moins de limitations, et notamment prendre en charge le rendu du texte.
Bien entendu, l’objectif est de décharger le plus possible le processus de rendu sur le GPU, en laissant le processeur libre d’exécuter du Javascript, de mettre à jour le DOM et de toutes les autres tâches.
Ainsi, bien que votre suggestion ne soit pas aussi extrême, elle va dans le sens de la conception d’une stratégie de calcul tenant compte à la fois du processeur et du processeur graphique.
la source
En vous concentrant sur les jeux (puisque vous en avez parlé spécifiquement dans votre message), vous pouvez équilibrer la charge de plusieurs manières. Un exemple est le "skinning", c'est-à-dire l'animation d'un modèle. Pour chaque image à restituer, vous devez générer les matrices de transformation pour chaque image d'animation et l'appliquer aux sommets du modèle afin de le transformer en pose à laquelle il doit être placé. Vous devez également interpoler les images pour obtenir un mouvement fluide. , sauf si vous souhaitez que votre animation ressemble au Quake original (c.-à-d. saccadé).
Dans ce cas, vous pouvez le faire sur le processeur et télécharger les résultats sur le GPU pour le rendu, ou effectuer le calcul et le rendu sur le GPU. Je pense qu’à présent, cela se fait sur le GPU (connu sous le nom de "skinning"): cela est logique étant donné que vous avez des calculs relativement simples qui doivent être effectués des milliers de fois, et que chaque sommet peut être calculé simultanément car le résultat du sommet A n'a aucune incidence sur le résultat du sommet B.
Cependant, en théorie, vous pouvez basculer de manière dynamique entre le traitement sur le processeur et le processeur graphique, en fonction de la surcharge du processeur graphique et du processeur.
Le principal obstacle à cette opération dans tous les calculs est toutefois que le processeur et le processeur graphique ont des forces et des faiblesses différentes. Les tâches massivement parallèles sont mieux effectuées sur le processeur graphique, tandis que les tâches linéaires intensives avec ramification sont mieux effectuées sur le processeur. Seuls quelques travaux pourraient être réalisés de manière réaliste sur les deux systèmes sans subir de graves conséquences en termes de performances.
Globalement, le principal problème de la programmation GPU (au moins avec OpenGL et DirectX 11 et inférieur) est que vous avez peu de contrôle sur la façon dont le GPU interprète votre code shader. Il est risqué de créer des branches dans un shader, car si vous créez accidentellement une dépendance entre les calculs, le processeur graphique peut alors décider de commencer à restituer vos pixels un par un, en passant de 60 ips à 10 ips en un instant, même si les données à restituer sont identiques.
la source
Un exemple concret est le moteur de rendu Open Source LuxRender , capable de charger entièrement un processeur et un processeur graphique en même temps. En outre, il peut charger plusieurs processeurs graphiques simultanément et peut également être distribué sur plusieurs ordinateurs.
LuxRender utilise OpenCL pour faciliter cela, bien qu'il existe également des versions sans OpenCL.
Ceci est pratique car les algorithmes utilisés par LuxRender sont hautement parallélisables. L'algorithme le plus couramment utilisé par LuxRender est le traçage de chemin , où de nombreux chemins de lumière peuvent être calculés indépendamment les uns des autres, ce qui constitue une situation idéale pour le calcul sur GPU et ne nécessite aucune synchronisation complexe entre les nœuds de calcul. Cependant, les limitations des GPU (faibles quantités de mémoire, manque de prise en charge de certaines fonctionnalités de rendu complexes et manque général de disponibilité pour certains artistes) garantissent que la prise en charge du processeur est toujours essentielle.
la source
Oui, c'est certainement possible.
Tout calcul qu'un processeur peut faire, un GPU peut aussi le faire, et inversement.
Mais c'est rare parce que:
Complexité technique Bien qu'il soit possible d'exécuter le même code sur une CPU et un GPU (par exemple, CUDA), les processeurs ont des capacités et des performances différentes. L'un est MIMD; l'autre, SIMD. Ce qui est rapide sur l'un est lent sur l'autre (par exemple, la création de branches), il est donc nécessaire d'écrire du code séparé pour optimiser les performances.
Rentabilité Les GPU sont globalement beaucoup plus puissants que les processeurs. L’idée des GPU est d’utiliser des processeurs moins chers, plus lents, mais plus nombreux pour effectuer des calculs bien plus rapidement que les processeurs ne le pourraient pour le même coût. Les GPU sont plus efficaces en termes de coûts d'un ou deux ordres de grandeur.
Si votre algorithme est exécuté sur des GPU, il est plus logique d’optimiser ces derniers et d’en ajouter autant que vous en avez besoin.
la source