Là où j'ai travaillé, nous utilisons toujours plusieurs niveaux de profilage; si vous voyez un problème, descendez un peu plus dans la liste jusqu'à ce que vous trouviez ce qui se passe:
- Le "profileur humain", alias juste jouer le jeu ; cela semble-t-il lent ou "attelé" à l'occasion? Vous remarquez des animations saccadées? (En tant que développeur, notez que vous serez plus sensible à certains types de problèmes de performances et inconscient des autres. Planifiez des tests supplémentaires en conséquence.)
- Activez l' affichage FPS , qui est un FPS moyen à fenêtre coulissante de 5 secondes. Très peu de frais généraux pour calculer et afficher.
- Activez les barres de profil , qui ne sont qu'une série de quads (couleurs ROYGBIV) qui représentent différentes parties du cadre (par exemple, vblank, preframe, update, collision, render, postframe) en utilisant un simple chronomètre "chronomètre" autour de chaque section de code . Pour souligner ce que nous voulons, nous avons défini une largeur d'écran d'une barre représentative d'une image cible à 60 Hz, il est donc très facile de voir si vous êtes, par exemple, 50% sous le budget (seulement une demi-barre) ou 50% au-dessus ( la barre s'enroule et devient une barre et demie). Il est également assez facile de dire ce qui mange généralement la plupart du cadre: rouge = rendu, jaune = mise à jour, etc.
- Construisez une construction instrumentée spéciale qui insère un "chronomètre" comme du code autour de chaque fonction. (Notez que vous pouvez prendre un énorme coup de performances, dcache et icache lorsque vous faites cela, donc c'est définitivement intrusif. Mais si vous manquez d'un profileur d'échantillonnage approprié ou d'un support décent sur le CPU, c'est une option acceptable. Vous pouvez également être intelligent. à propos de l'enregistrement d'un minimum de données sur la fonction entrée / sortie et la reconstruction des traces d'appels plus tard.) Lorsque nous avons construit les nôtres, nous avons imité une grande partie du format de sortie de gprof .
- Mieux encore, exécutez un profileur d'échantillonnage ; VTune et CodeAnalyst sont disponibles pour x86 et x64, vous disposez de divers environnements de simulation ou d'émulation qui pourraient vous fournir des données ici.
(Il y a une histoire amusante d'un GDC d'un an d'un programmeur graphique qui a pris quatre photos de lui-même - heureux, indifférent, ennuyé et en colère - et a affiché une image appropriée dans le coin des constructions internes basée sur le framerate. les créateurs de contenu ont rapidement appris à ne pas activer les shaders compliqués pour tous leurs objets et environnements: ils mettraient le programmeur en colère. Contemplez le pouvoir du feedback.)
Notez que vous pouvez également faire des choses amusantes comme représenter graphiquement les "barres de profil" en continu, de sorte que vous pouvez voir les modèles de pointes ("nous perdons une image toutes les 7 images") ou similaires.
Pour répondre à votre question directement, cependant: d'après mon expérience, bien qu'il soit tentant (et souvent gratifiant - j'apprends généralement quelque chose) de réécrire des fonctions / modules uniques pour optimiser le nombre d'instructions ou les performances icache ou dcache, et nous devons réellement le faire parfois, lorsque nous avons un problème de performance particulièrement désagréable, la grande majorité des problèmes de performance que nous traitons régulièrement se résument à la conception . Par exemple:
- Doit-on mettre en cache dans la RAM ou recharger à partir du disque les images d'animation d'état "d'attaque" pour le joueur? Et pour chaque ennemi? Nous n'avons pas de RAM pour tout faire, mais les charges de disque sont chères! Vous pouvez voir l'attelage si 5 ou 6 ennemis différents apparaissent en même temps! (D'accord, que diriez-vous d'un frai étonnant?)
- Faisons-nous un seul type d'opération sur toutes les particules, ou toutes les opérations sur une seule particule? (Il s'agit d'un compromis icache / dcache, et la réponse n'est pas toujours claire.) Que diriez-vous de séparer toutes les particules et de stocker les positions ensemble (la fameuse "structure des tableaux") vs de conserver toutes les données de particules en un seul endroit (" tableau de structures ").
Vous l'entendez jusqu'à ce qu'il devienne désagréable dans les cours d'informatique de niveau universitaire, mais: il s'agit vraiment de structures de données et d'algorithmes. Passer du temps sur la conception d'algorithmes et de flux de données vous permettra d'en avoir plus pour votre argent en général. (Assurez-vous que vous avez lu les excellents pièges de la programmation orientée objet d'un collègue de Sony Developer Services pour un aperçu ici.) Cela ne "ressemble" pas à l'optimisation; c'est surtout du temps passé avec un tableau blanc ou un outil UML ou à créer de nombreux prototypes, plutôt que d'accélérer l'exécution du code actuel. Mais cela vaut généralement beaucoup plus la peine.
Et une autre heuristique utile: si vous êtes proche du «cœur» de votre moteur, cela peut valoir un effort supplémentaire et une expérimentation à optimiser (par exemple vectoriser ces multiplications de matrice!). Plus vous vous éloignez du cœur, moins vous devriez vous en préoccuper, à moins que l'un de vos outils de profilage ne vous dise le contraire.