Micro-optimisation - BAD vs Game Development


12

Dans le développement de jeux, il y a beaucoup de C / C ++, dans les applications métier C #. J'ai vu des développeurs C / C ++ exprimer leur inquiétude quant à la façon dont une seule ligne de code se traduit par l'assembly. Dans .NET, certains vont rarement en IL.

En C #, la «micro-optimisation» est mal vue, rare et généralement une perte de temps. Cela ne semble pas être le cas dans le développement de jeux.

Qu'est-ce qui crée spécifiquement cette incohérence? Les jeux repoussent-ils constamment les limites du matériel? Si oui, à mesure que le matériel s'améliore, devrions-nous nous attendre à ce que des langages de niveau supérieur prennent le contrôle de l'industrie du jeu?

Je ne cherche pas un débat sur la faisabilité de C # en tant que jeu dev lang. Je sais que cela a été fait dans une certaine mesure. Focus sur la micro-optimisation. Plus précisément, la différence entre Game Dev et Applications dev.

MISE
À JOUR Par jeu, je veux dire un développement moderne à grande échelle. EG MMORPG, Xbox, PS3, Wii ...


3
J'ai travaillé en tant que développeur de jeux et développeur d'applications et les différences sont sans objet. La micro-optimisation sans profilage est mal vue dans les deux. De nombreux jeux n'ont pas d'exigences très puissantes et ne nécessitent aucune optimisation. Certaines applications professionnelles nécessitent des exigences beaucoup plus strictes (par exemple, disponibilité et garanties en temps réel) qu'un jeu moyen à 60 Hz.
Dave Hillier

1
Un facteur supplémentaire est que dans les applications d'entreprise, vous pouvez généralement choisir le matériel (dans des limites raisonnables). Si j'ai besoin de plus de puissance de traitement, je peux simplement acheter un autre serveur ou payer plus de temps sur AWS. Dans les jeux, nécessiter le dernier matériel transforme un jeu de 60 $ en jeu et carte vidéo de 1 060 $. Si vous développez pour des consoles, la mise à niveau du matériel peut signifier retarder pendant des années l'attente de la prochaine génération. Lorsque vous ne pouvez pas obtenir un meilleur matériel, vous devez en faire un meilleur usage.
Andrew

Réponses:


17

Dans les applications d'entreprise, le processeur n'est pas toujours le goulot d'étranglement. Une application métier passerait la plupart du temps à attendre. Par exemple:

  1. en attente des résultats de la requête de base de données
  2. en attente de la fin de la demande Web
  3. attendre que l'utilisateur effectue une action d'interface utilisateur

C'est pourquoi le code qui optimise les performances de traitement n'ajoute pas trop de valeur.

La considération principale est:

  1. Délai de mise sur le marché
  2. Simplicité, quelqu'un d'autre peut-il comprendre et maintenir le code

6
Je voudrais souligner que le code qui optimise les requêtes de base de données peut grandement améliorer la convivialité des applications métier.
HLGEM

4
+1. L'optimisation de la base de données et du réseau donnerait généralement plus pour son argent dans l'application métier. Par exemple, choix des index JSON vs XML et tuning DB
Shamit Verma

2
+1 mais il faut ajouter l'autre côté de l'équation: la ou les "boucle (s) principale (s)" et le (s) rendu (s) dans les jeux sur lesquels la fluidité du jeu repose font que chaque microseconde perd une perte de valeur, car la qualité est perceptible à l'œil et à d'autres sens.
Klaim

1
Bien dit. Et en effet, après avoir fait des applications commerciales et le développement de jeux, j'ai passé du temps à examiner une requête SQL complexe en essayant d'améliorer les performances, tout comme j'ai passé du temps à parcourir une boucle interne dans un jeu.
Carson63000

Tout revient à l' optimisation prématurée est la racine de tout mal . Le profilage révèle clairement que la plupart du temps passé dans votre application métier moyenne est un réseau + une base de données d'E / S.
Alex Reinking

13

Dans les applications commerciales, il est très rare que les microsecondes importent. Dans les jeux, c'est une réalité de la vie.

Si vous voulez qu'un jeu tourne à 60 images par seconde, vous avez ~ 16,67 millisecondes pour faire tout ce qui doit être fait pour cette image - entrée, physique, logique de jeu, audio, mise en réseau, IA, rendu, etc. si vous êtes chanceux, vous courrez à 30 images par seconde et aurez un luxueux 33,3 millisecondes. Si un cadre prend trop de temps, vos critiques en souffriront, vos joueurs rempliront les forums Internet de bile et vous ne vendrez pas autant que vous le pourriez (sans parler du coup porté à votre fierté professionnelle) et si vous êtes vraiment malchanceux, vous trouvera votre équipe de codage d'applications professionnelles pour vivre.

Bien sûr, les développeurs de jeux ne se soucient pas de chaque ligne, car avec l'expérience et un profileur décent, vous apprenez quelles lignes doivent vous inquiéter. D'un autre côté, ces inquiétudes touchent parfois des choses qui dans le monde des affaires seraient probablement considérées comme des nano-optimisations plutôt que des micro-optimisations.

Ne vous attendez pas à ce qu'un langage de haut niveau lance le C ++ jusqu'à ce qu'il offre des performances comparables et prévisibles.


8
Dans les applications de trading haute fréquence, les microsecondes comptent beaucoup!
quant_dev

2
@quant: comme avec la plupart des applications de traitement de flux - robotique, réseaux électriques, fusée, technologie médicale, etc. Créez trop de carnet de commandes et il peut être trop tard au moment où vous rattrapez votre retard.
Aaronaught

@quant_dev: Les applications de trading haute fréquence sont très rares.
molbdnilo

Plus maintenant. Ils sont plus rares que les applications comptables, mais plus courants que, disons, les logiciels de conception d'avion.
quant_dev

Les microsecondes comptent également dans les applications d'entreprise, le goulot d'étranglement se trouve généralement ailleurs (sur le réseau, dans une base de données ou un système de fichiers).
RubberDuck

9

D'accord, vous avez donc vu des développeurs C et C ++ obsédés par des lignes individuelles. Je parie qu'ils ne sont pas obsédés par chaque ligne.

Il y a des cas où vous voulez des performances maximales, et cela inclut beaucoup de jeux. Les jeux ont toujours essayé de repousser les limites de performances, afin de mieux paraître que leurs concurrents sur le même matériel. Cela signifie que vous appliquez toutes les techniques d'optimisation habituelles. Commencez avec des algorithmes et des structures de données, et continuez à partir de là. En utilisant un profileur, il est possible de trouver où le plus de temps est pris et où il est possible d'obtenir des gains importants en micro-optimisant quelques lignes.

Ce n'est pas parce que les langues forcent les gens à cela, c'est que les gens choisissent des langues en fonction de ce qu'ils veulent faire. Si vous voulez arracher le dernier bit de performance d'un programme, vous n'écrirez pas C # et ne compilerez pas dans le CLR et espérez que le compilateur JIT (ou autre) fera du bon travail, vous l'écrivez dans quelque chose que vous pouvez contrôler en grande partie le résultat. Vous utiliserez C ou C ++ (et probablement un sous-ensemble restreint de C ++) et étudierez la sortie en langage assembleur et les résultats du profileur.

Il y a beaucoup de gens qui utilisent C et C ++ et ne se soucient pas trop des détails de la traduction, tant que cela semble assez rapide.


7

Les jeux repoussent-ils constamment les limites du matériel?

Oui, ils le font.

Si oui, à mesure que le matériel s'améliore, devrions-nous nous attendre à ce que des langages de niveau supérieur prennent le contrôle de l'industrie du jeu?

Pas vraiment - car à mesure que le matériel s'améliore, les consommateurs s'attendent à ce que les jeux s'améliorent également. Ils ne s'attendent pas à voir la même qualité de jeu développée plus efficacement car les développeurs ont utilisé un langage de niveau supérieur. Ils s'attendent à voir leurs chaussettes emportées par chaque nouvelle plateforme.

Bien sûr, il y a du mouvement. Quand j'étais enfant et que je m'intéressais pour la première fois au développement de jeux, il s'agissait d'assemblage manuscrit, ou de l'enfer. C'était l'ère Commodore 64. De nos jours, bien sûr, C ++ est la lingua franca de la plupart des développements de jeux. Et en effet, nous avons même observé un mouvement vers l'utilisation de C ++ pour le code moteur et d'un langage de script de niveau supérieur pour le code logique du jeu. par exemple LUA, ou le moteur Unreal a son propre langage UnrealScript.


1
+1 une bonne partie des développeurs de jeux utilisent de nos jours une couche de moteur hyper-optimisée écrite par quelqu'un d'autre, puis utilisent quelque chose comme Python, ou un C ++ moins méticuleux pour envelopper les choses ensemble.
Morgan Herlocker

Il convient de noter qu'Unreal a désormais déplacé ses scripts «en arrière», d'UnrealScript vers C ++. C'est une grande chose au sujet du C ++ moderne qu'il vous permet d'écrire à la fois du code à faible latence micro-optimisé et une logique de haut niveau concise. La plupart des autres langues n'atteignent un niveau élevé qu'en sacrifiant la latence et souvent aussi les performances.
leftaroundabout

7

En C #, la «micro-optimisation» est mal vue, rare et généralement une perte de temps. Cela ne semble pas être le cas dans le développement de jeux.

Si vous pouvez simplement assembler votre application avec du code de haut niveau et du code de bibliothèque, c'est certainement une perte de temps. Écrivez-le dans une langue interprétée si vous le souhaitez dans ce cas; ne fera pas beaucoup de différence. Si vous essayez de mettre en œuvre un moteur d'éclairage global de pointe qui voxélise le contenu de scène dynamique à la volée en temps réel comme l'a fait CryEngine 3 , vous ne pouvez naturellement pas échapper au besoin de micro-optimiser.


0

"Jeu" est un terme assez englobant. Si vous aviez, disons, un MMORPG, de plus petites optimisations affecteraient de nombreux joueurs.

Les joueurs sont, et ont probablement toujours été habitués à un nombre relativement important de choses qui se produisent à la fois, en temps réel. Sûr; à un moment donné, avoir un Pacman ou Tetris réactif était l'objectif. Mais ils devaient encore être réactifs. De nos jours, 3DMMORPG sur des connexions réseau à perte de paquets.

Je comprends bien le désir d'optimiser.


0

Les jeux font constamment d'énormes quantités de traitement en arrière-plan. Les applications professionnelles ne le font pas.


4
Ne faites pas beaucoup d'applications professionnelles, n'est-ce pas?
JUSTE MON AVIS correct

2
Assez pour savoir que les applications d'entreprise n'ont pas besoin de mettre à jour leur statut 60 fois par seconde. De plus, j'ai spécifiquement dit "constamment".
user16764

2
Avez-vous déjà entendu parler du trading en temps réel?
JUSTE MON AVIS correct

0

J'ai toujours trouvé le terme «micro-optimisation» assez ambigu. Si certains changements au niveau de l'instruction de la disposition de la mémoire et des modèles d'accès rendent quelque chose 80 fois plus rapide d'un professionnel discipliné mesurant leurs points d'accès sans réduction à la complexité algorithmique, est-ce une "micro-optimisation"? Pour moi, c'est une "méga-optimisation" pour rendre quelque chose 80 fois plus rapide dans un cas d'utilisation réel. Les gens ont tendance à parler de ces choses comme ces optimisations ont des effets microscopiques.

Je ne travaille plus dans gamedev mais je travaille dans VFX dans des domaines comme le traçage de chemin, et j'ai vu de nombreuses implémentations d'arbres BVH et KD qui traitent ~ 0,5 million de rayons par seconde sur une scène complexe (et c'est avec évaluation multithread). En gros, j'ai tendance à voir une implémentation simple d'un BVH dans un contexte de raytracing à moins de 1 million de rayons / sec, même avec une évaluation multithread. Sauf qu'Embree a un BVH qui peut traiter plus de 100 millions de rayons sur la même scène avec le même matériel.

Cela est entièrement dû aux "micro-optimisations" qu'Embree est 200 fois plus rapide (même algorithme et structure de données), mais bien sûr, la raison pour laquelle c'est tellement plus rapide est que les développeurs d'Intel derrière lui sont des professionnels qui s'appuient sur leurs profileurs et leurs mesures et vraiment réglé les domaines qui comptaient. Ils ne changeaient pas le code de bon gré des intuitions et ne commettaient pas de modifications qui ont apporté des améliorations de 0.000000001% au prix d'une dégradation significative de la maintenabilité. Il s'agissait d'optimisations très précises appliquées entre des mains judicieuses - elles pouvaient être microscopiques en termes de focalisation mais macroscopiques en termes d'effet.

Naturellement avec les exigences de taux de trame en temps réel des jeux, selon le niveau ou le niveau bas dans lequel vous travaillez avec le moteur de jeu (même les jeux créés avec UE 4 sont souvent implémentés au moins partiellement dans un script de haut niveau, mais pas, disons, les parties les plus critiques du moteur physique), les micro-optimisations deviennent une exigence pratique dans certains domaines.

Un autre domaine très basique qui nous entoure quotidiennement est le traitement d'image, comme le flou d'images haute résolution en temps réel et peut-être leur faire d'autres effets dans le cadre d'une transition que nous avons probablement tous vu quelque part, peut-être même un effet de système d'exploitation. Vous ne pouvez pas nécessairement implémenter de telles opérations d'image à partir de zéro en bouclant tous les pixels d'une image et vous attendre à de tels résultats en temps réel à des fréquences d'images correspondantes. Si c'est un processeur, nous examinons généralement SIMD et certains micro-réglages, ou nous examinons les shaders GPU qui nécessitent généralement une sorte de mentalité au niveau micro pour écrire efficacement.

Si oui, à mesure que le matériel s'améliore, devrions-nous nous attendre à ce que des langages de niveau supérieur prennent le contrôle de l'industrie du jeu?

Je doute plutôt que les progrès du matériel à eux seuls puissent le faire, car au fur et à mesure que le matériel progresse, les instructions et la technologie (ex: physique sur GPU), les techniques et les attentes des clients pour ce qu'ils veulent voir et la concurrence des moyens qui font souvent revenir les développeurs à bas niveau, comme dans le cas même des développeurs Web qui écrivent maintenant des shaders GLSL de bas niveau dans WebGL (le développement Web de ce type particulier est sans doute encore plus bas qu'il y a une décennie ou deux, car GLSL est un langage de type C extrêmement bas, et je n'aurais jamais imaginé il y a une décennie ou deux que certains développeurs Web accepteraient d'écrire de tels shaders GPU de bas niveau).

S'il doit y avoir un moyen pour les domaines critiques pour les performances de passer à des langages de niveau supérieur, cela devra provenir davantage des logiciels, des compilateurs et des outils dont nous disposons à mon avis. Dans un avenir prévisible, le problème n'est pas que le matériel ne soit pas assez puissant. Cela a plus à voir avec la façon dont nous ne pouvons pas trouver les moyens de lui parler le plus efficacement chaque fois qu'il change et avance sans revenir à sa propre langue. C'est en fait le rythme rapide auquel le matériel change qui rend la programmation de haut niveau plutôt insaisissable pour ces domaines comme je le vois, car si hypothétiquement notre matériel a cessé d'avancer à l'improviste pendant les décennies suivantes,

Curieusement ces jours-ci, quand je travaille dans de véritables domaines critiques pour les performances, je dois penser un peu plus bas que j'ai commencé (même si j'ai commencé à l'ère Borland Turbo C DOS). Parce qu'à l'époque, le cache du processeur était presque inexistant. Il s'agissait principalement de DRAM et de registres, ce qui signifiait que je pouvais me concentrer davantage sur la complexité algorithmique et écrire des structures liées comme des arbres de manière très simple sans trop affecter les performances. De nos jours, les détails de bas niveau du cache CPU dominent ma pensée presque autant que l'algorithme lui-même. Et de même, nous avons des machines multi-cœurs qui doivent nous faire penser au multithreading et à l'atomique et aux mutex et à la sécurité des threads et aux structures de données simultanées, etc. dans, pas si intuitivement humainement) que quand j'ai commencé.

Curieusement, cela me semble très vrai maintenant. Je pense que je suis plus impacté par les complexités et les détails sous-jacents et de bas niveau du matériel aujourd'hui qu'il y a 30 ans, faisant de mon mieux pour enlever les lunettes de nostalgie. Bien sûr, nous aurions pu parler un peu d'assemblage ici et avoir dû traiter de quelques détails sanglants comme XMS / EMS. Mais pour la plupart, je dirais qu'il y avait moins de complexité et de sensibilisation au matériel et au compilateur dont j'avais besoin à l'époque qu'à l'heure actuelle lorsque je travaille dans des domaines critiques pour les performances. Et cela semble presque vrai pour l'ensemble de l'industrie si nous mettons de côté comme l'écritureif/else déclarations d'une manière légèrement plus lisible par l'homme et considérer combien de personnes en général ces jours-ci pensent davantage aux détails de niveau inférieur du matériel (de plusieurs cœurs aux GPU à SIMD au cache CPU et les détails internes de la façon dont leurs compilateurs / interprètes / les bibliothèques fonctionnent, etc.).

Niveau élevé! = Moins efficace

Pour en revenir à cette question:

Si oui, à mesure que le matériel s'améliore, devrions-nous nous attendre à ce que des langages de niveau supérieur prennent le contrôle de l'industrie du jeu?

Pour moi, ce n'est pas une question de matériel. Il s'agit d'optimiseurs et d'outils. Quand j'ai commencé, les gens écrivaient pratiquement tous les jeux de console en assemblage, et il y avait un véritable avantage en termes de performances, surtout compte tenu du manque de compilateurs de qualité générant 6502.

L'optimisation des compilateurs C est devenue plus intelligente dans leurs optimisations, puis ils ont commencé à atteindre un point où le code de niveau supérieur écrit en C rivalisait et parfois même surpassait le code écrit par les meilleurs experts de l'assemblage dans de nombreux domaines (mais pas toujours), et cela a fait en sorte qu'il était alors évident d'adopter le C pour au moins la majeure partie du codage d'un jeu. Et un changement similaire s'est progressivement produit à un moment donné avec C ++. L'adoption de C ++ a été plus lente car je pense que l'augmentation de la productivité du passage de l'assemblage au C pourrait probablement atteindre l'accord unanime de gamedevs écrivant des jeux non triviaux entièrement en ASM par opposition au passage du C au C ++.

Mais ces changements ne sont pas dus au fait que le matériel est devenu plus puissant que les optimiseurs pour ces langages qui sont devenus de plus bas niveau (bien que pas toujours entièrement, il y a des cas obscurs) obsolètes.

Si vous pouvez imaginer un scénario hypothétique où nous pourrions écrire du code dans le code de plus haut niveau imaginable, sans se soucier du multithreading ou des GPU ou des échecs de cache ou quelque chose comme ça (peut-être même pas des structures de données spécifiques), et l'optimiseur était comme l'intelligence artificielle intelligent et pourrait comprendre les dispositions de mémoire les plus efficaces en réarrangeant et en compactant nos données, comprendre qu'il pourrait utiliser un GPU ici et là, paralléliser du code ici et là, utiliser un SIMD, peut-être se profiler et continuer à optimiser son IR comme nous les humains répondre aux hotspots du profileur, et cela l'a fait d'une manière qui bat les meilleurs experts du monde, alors ce serait une évidence pour même ceux qui travaillent dans les domaines les plus critiques pour les performances de l'adopter ... et c'est une avancée provenant d'optimiseurs ridiculement intelligents, pas de matériel plus rapide.


0

En C #, la «micro-optimisation» est mal vue, rare et généralement une perte de temps. Cela ne semble pas être le cas dans le développement de jeux.

Vous avez un problème de terminologie ici. Vous utilisez les mots correctement, mais les développeurs de jeux et les gens d'affaires utilisent le même terme de deux manières très différentes.

Pour les entreprises, la «micro-optimisation» signifie accélérer une toute petite étape du processus commercial global mis en œuvre par le logiciel. La raison pour laquelle il est mal vu est généralement l'une des suivantes:

  1. De l'argent supplémentaire dépensé pour offrir la même valeur commerciale, à une vitesse plus rapide de quelques secondes. L'argent économisé grâce aux améliorations de la vitesse provient d'un pool d'argent différent (le temps de l'utilisateur), de sorte que l'entreprise ne bénéficie généralement pas des efforts qu'elle déploie, le client le fait aux dépens de l'entreprise.
  2. En règle générale, les programmeurs métier ont une mauvaise visibilité dans le processus métier global, de sorte qu'une optimisation d'une seule étape peut ne pas générer de bons avantages pour le processus global. Par exemple, si vous accélérez 3% du processus 10 fois, vous avez accéléré l'ensemble du processus de 2,7%.
  3. En règle générale, les entreprises ont une grande liste de travaux restants qui ont une certaine valeur commerciale et prioriseraient l'ajout de cette valeur au lieu de fournir la même valeur dans un délai (probablement) plus court.

Le développement de jeux est une bête différente. la "micro optimisation" permet de gagner un peu de temps dans une fonction ou une routine.

  1. Les systèmes de jeu ont tendance à être liés au cycle de rendu. Actuellement, la norme d'or est de 60 images par seconde, donc tout ce qui va être calculé doit être fait et rendu à l'écran en 1 / 60e de seconde.
  2. Cela signifie que souvent les mêmes routines sont appelées des milliers à des centaines de milliers de fois au cours d'une partie. Ainsi, une amélioration de 10 fois dans une seule fonction est amplifiée en valeur par le nombre de fois où les avantages de l'amélioration se feront sentir.
  3. L'échec à atteindre le taux de rendu a un impact sur la présentation du jeu. La vidéo deviendra saccadée, les personnages s'animeront avec des sauts et des sauts au lieu d'un mouvement fluide. Cela fait immédiatement sortir le joueur de l'immersion du jeu, et dans le domaine de la remise en question de la valeur du jeu.

Donc, en affaires, personne ne se soucie si la forme d'un processus métier en 4 étapes se présente en 0,6 seconde ou 0,5 seconde. Pendant le jeu, on se soucie si une routine qui prend 200 ms peut être réduite à une exécution en 100 ms.

Tout dépend de la valeur apportée au client, de ses besoins et du rapport coût-bénéfice du changement.


-1

Cela a à voir avec la raison pour laquelle cet outil a été sélectionné pour un travail particulier.

Les golfeurs seront obsédés par la direction et la force qu'ils appliquent avec un putter, pas tant lorsqu'ils utilisent le pilote.

Pourquoi? Parce que ce sont des types de photos différents. Pour un lecteur, vous voulez l'obtenir dans le fairway avec une distance maximale. Pour un putt, vous voulez l'obtenir exactement dans le trou.

Il en va de même ici. Les développeurs de jeux choisissent C ++ car il leur donne le contrôle sur les performances des différentes opérations. Si vous avez choisi cela, vous allez vouloir en tirer parti.


-3

La plupart des applications métier sont écrites comme des outils internes. Les attentes quant à l'utilisabilité de ces outils sont beaucoup plus faibles que dans le cas des logiciels vendus à des clients de masse. Il est assez courant qu'une application d'entreprise interne ait des menus et des boîtes de dialogue qui réagissent lentement aux clics de souris, des fenêtres qui se redessinent avec retard, ou même une interface graphique écrite en Swing (l'horreur!). Ceci pour un certain nombre de raisons (il est plus important que le logiciel soit personnalisable que très "accrocheur", les utilisateurs du logiciel n'ont pas le choix d'utiliser ou non le logiciel en question, les personnes qui font le décision d'installer le logiciel ne l'utilisez pas eux-mêmes ...). La conséquence de tout cela est que les développeurs de ces outils ne passent pas beaucoup de temps à optimiser la réactivité de l'application, mais se soucient beaucoup de l'extensibilité et du nombre de fonctionnalités. Clientèle différente => objectifs de conception différents => méthodologie différente.

Notez qu'une application métier ciblant un public de masse, comme Excel, EST fortement optimisée.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.