Principaux problèmes pour les titres Windows
Le groupe Microsoft Windows Gaming and Graphics Technologies Developer Relations effectue une analyse des performances pour de nombreux jeux Windows chaque année. Au cours de ces sessions, nous obtenons une expérience pratique pour nous lier aux commentaires et aux requêtes des développeurs que nous recevons quotidiennement. Parfois, nous aidons à trouver un incident mystérieux ou un autre problème dans un titre, ce qui nous donne un aperçu plus approfondi des problèmes que les développeurs rencontrent.
Cet article met en évidence la plupart des problèmes courants que nous avons rencontrés dans les jeux PC de génération actuelle.
- Performances limitées du processeur
- Gestion des lots médiocre
- Copie de mémoire excessive
- Utilisation excessive de la soumission de dessin dynamique
- Surcharge élevée dans le traitement des fichiers
- Installation lente et frustrante
- Absence de prise en compte de la mémoire physique
- Sur-dépendance à l’égard de la conversion de taux d’échantillonnage audio Real-Time
- Fragmention de la mémoire virtuelle
- Manipulation du Word de contrôle Floating-Point
- Installation facultative du runtime DirectX
- Utilisation excessive de la synchronisation de threads
- Utilisation de RDTSC
performances CPU-Limited
La grande majorité des jeux sont limités par les performances du processeur sur les systèmes dotés d’unités de traitement graphique (GPU) hautes performances. Cela est parfois dû à une mauvaise utilisation du traitement par lot pour les soumissions de tirages, mais plus généralement, cela est dû au fait que d’autres systèmes de jeu consomment une grande partie des cycles de processeur disponibles. Dans les rares cas où nous avons vu le GPU comme la limitation, la cause est des taux de remplissage très élevés ou la demande de nuanceur de pixels, dans les paramètres de haute résolution, ou de faibles performances de nuanceur de vertex par un carte vidéo.
Étant donné que la plupart des titres sont limités au processeur, les gains de performances les plus importants proviennent de l’optimisation des systèmes de jeu gourmands en ressources processeur. En règle générale, les systèmes d’IA ou de physique et la logique de détection de collision associée sont les principaux consommateurs de cycles d’UC dans les applications Microsoft Direct3D qui se comportent bien. Tout travail visant à améliorer ces systèmes peut améliorer les performances globales du jeu.
Gestion des lots médiocre
Pour obtenir un bon parallélisme avec le GPU, les lots de dessins contiennent suffisamment de géométrie (et les nuanceurs ont la complexité appropriée) pour occuper la vidéo carte, tout en n’utilisant pas autant de lots que la mémoire tampon de commande est inondée. Sur le matériel de génération actuelle, nous recommandons d’environ 300 soumissions par lot de dessins par image (moins sur les processeurs de faible performance) afin d’éviter que le traitement de la mémoire tampon de commande par le pilote ne devienne un goulot d’étranglement des performances. Certains autres appels d’état d’API et combinaisons de pilotes peuvent entraîner un traitement coûteux du processeur (compilation de pilotes de nuanceurs, par exemple), nous vous recommandons vivement d’effectuer une analyse de routine des performances.
Copie de mémoire excessive
Pendant le développement de la plupart des titres de PC, les développeurs utilisent des structures de données et des chaînes pratiques pour la gestion de contenu. Le travail du processeur requis pour la comparaison de chaînes, la copie et d’autres manipulations a souvent une surcharge mesurable, en particulier en tenant compte des performances associées au sous-système de cache et de mémoire. Des plans doivent être élaborés lors du développement de ces systèmes pour supprimer ou réduire au minimum la dépendance à l’égard du traitement de chaînes une fois que le produit entre dans les phases principales de test et de mise en production.
Utilisation excessive de la soumission de dessin dynamique
Le matériel vidéo moderne fonctionne bien quand vous traitez des données statiques. Les adaptateurs haut de gamme ont souvent une très grande quantité de mémoire vidéo, mais cette mémoire ne peut pas être utilisée efficacement par les données dynamiques.
Bien que des modèles d’utilisation relativement efficaces des mémoires tampons de vertex dynamiques/mémoires tampons d’index puissent être implémentés pour le contenu dynamique, de nombreux titres surutilisent cet idiome pour ce qui est autrement du contenu statique. Nous le voyons le plus souvent avec les arborescences de partitionnement d’espace binaire (BSP) et les systèmes basés sur le portail qui stockent la géométrie dans une structure de données qui ne correspond pas au matériel et qui doit être traitée en mémoire tampon pour chaque image. Le fait de placer autant de contenu dans des ressources statiques que possible peut réduire considérablement la surcharge de bande passante liée au transfert de données vers le carte vidéo, mieux utiliser la VRAM intégrée et réduire la surcharge processeur/cache impliquée dans le traitement de ce contenu.
Surcharge élevée dans le traitement des fichiers
Les jeux PC ont une réputation pour les temps de chargement longs, en particulier par rapport aux titres de console avec des exigences strictes de temps de chargement. Notre analyse de la façon dont de nombreux titres utilisent le sous-système de fichiers révèle certains problèmes courants.
La surcharge liée à l’ouverture d’un fichier est généralement beaucoup plus élevée que ce que les développeurs attendent. Avec les scanneurs antivirus à la demande largement utilisés et les fonctionnalités supplémentaires de NTFS, l’ouverture d’un fichier est une opération assez coûteuse. L’ouverture de plusieurs fichiers à la fois ou l’ouverture et la fermeture répétées d’un même fichier sont donc une mauvaise méthode de gestion des fichiers. Certains jeux ont tenté d’atténuer ce coût de performances en testant l’existence d’un fichier avant de l’ouvrir. La réalité étant que le test de l’existence d’un fichier sur NTFS nécessite l’ouverture du fichier, les tests avant d’ouvrir entraînent le paiement du coût deux fois.
Les jeux qui autorisent des modifications de module complémentaire, ou des mods, ou qui incluent toujours la génération de modèles de développement pour case activée pour les fichiers de données de remplacement, peuvent avoir des retards importants dans le chargement du jeu en raison de la vérification de ces fichiers, même lorsque ces fichiers ne sont pas présents. Nous recommandons que les jeux case activée uniquement pour ces fichiers lorsqu’ils sont exécutés avec un commutateur de ligne de commande spécial ou un autre indicateur de mode, de sorte que seuls les utilisateurs qui utilisent cette fonctionnalité paient réellement le coût des performances de ces vérifications (souvent étendues).
Des performances supplémentaires peuvent être obtenues à partir du système de fichiers en procédant comme suit :
- Utilisation appropriée des indicateurs de système de fichiers FILE_FLAG_RANDOM_ACCESS et FILE_FLAG_SEQUENTIAL_SCAN
- Dimensionnement des mémoires tampons pour éviter une grande quantité d’appels aux API de lecture/écriture du système d’exploitation
- Accès asynchrone aux fichiers
- Chargement de threads en arrière-plan
Nous vous recommandons également vivement de convertir les données hors connexion (au moment de la génération ou de l’installation) plutôt que de vous fier à la conversion lors de la première exécution du jeu, car cela impose une taxe de performances importante pour chaque utilisateur.
Installation lente et frustrante
Un autre problème courant que nous avons rencontré est le temps d’installation très long nécessaire pour de nombreux jeux PC modernes. Les programmes d’installation invitent l’utilisateur à plusieurs reprises, parfois simplement à le dire, par exemple , « Vous n’avez pas besoin de DirectX installé ». En règle générale, ces programmes d’installation incriminés nécessitent que l’utilisateur sélectionne Suivant ou OK plusieurs fois avant que l’installation du jeu ne commence réellement. Une fois qu’il a commencé, nous avons vu certains titres prendre une heure ou plus avant que l’utilisateur ait la possibilité de jouer au jeu. Nous pensons fermement que la première heure de l’expérience de jeu ne doit pas être l’installation.
Nous recommandons plusieurs approches pour gérer l’installation. Tout d’abord, gardez les invites simples et au minimum. Deuxièmement, concevez vos données de jeu de telle sorte que tout ou partie des fichiers de données puissent être utilisés directement à partir du disque de distribution lorsque cela est possible . Les lecteurs de DVD modernes ont une bande passante très élevée. Troisièmement, envisagez d’implémenter l’installation à la demande dans vos titres pour réduire ou éliminer le processus d’installation et permettre aux utilisateurs d’accéder au jeu aussi rapidement que possible. (Pour plus d’informations sur l’installation à la demande, consultez Installer à la demande pour les jeux.)
Pour obtenir d’autres recommandations sur l’installation du jeu, consultez Simplification de l’installation du jeu.
Absence de prise en compte de la mémoire physique
En raison de la grande variabilité du matériel PC sur le marché, les titres utilisent généralement des tests de configuration ad hoc pour sélectionner les paramètres par défaut pour le niveau de détail graphique. Certains des titres que nous avons vus utilisent la taille de la mémoire vidéo dans ces tests, mais ne parviennent pas à la mettre en corrélation avec la taille de la mémoire physique. Pour gérer les situations de perte d’appareil, la majeure partie de la mémoire vidéo (à la fois la VRAM locale sur le carte et l’ouverture de mémoire AGP non locale) doit être soutenue par de la mémoire physique, soit via l’utilisation de ressources managées ou de structures de données personnalisées. Certaines cartes vidéo haut de gamme ont des tailles VRAM qui rivalisent avec la taille des mémoires processeur bas de gamme. Dans les situations où le système dispose d’une mémoire physique limitée par rapport à la vidéo carte, la plupart de ces VRAM ne peuvent pas être utilisées efficacement et des paramètres plus détaillés doivent être configurés.
Over-Reliance sur Real-Time conversion de taux d’échantillonnage audio
Une autre source courante de gravure du cycle du processeur que nous avons vu se produit lorsque le système audio est nécessaire pour convertir le taux de lecture pendant la combinaison en mémoire tampon matérielle. Avec les pilotes WDM (Windows Driver Model), le format de mémoire tampon matérielle n’est pas sous contrôle direct de l’application, car il s’agit d’une ressource au niveau du noyau ; Au lieu de cela, le format est sélectionné en fonction du format de qualité supérieure de toutes les sources et des fonctionnalités du matériel. Par défaut, Windows XP utilise une conversion de taux d’échantillonnage de haute qualité pour ce processus, et si la majorité des échantillons audio nécessitent une conversion de taux, une partie importante des cycles de processeur est consommée.
Nous vous recommandons de créer toutes vos mémoires tampons DirectSound avec le même taux d’échantillonnage. Si vous utilisez les fonctions waveOut de Microsoft Win32, vous devez également utiliser un taux d’échantillonnage cohérent avec celles-ci. Avec les pilotes WDM, les mémoires tampons sont toutes mélangées par le noyau, et si vous utilisez un taux d’échantillonnage plus élevé sur certains d’entre eux, les taux d’échantillonnage de tous les autres sont convertis pour correspondre. Notez que cela implique l’utilisation du même taux de lecture pour tous vos échantillons audio, y compris les mémoires tampons de décompression audio en streaming. La définition du taux de mémoire tampon principal n’a aucun effet, sauf si vous ciblez Windows 98 ou Windows Millennium Edition.
Notes
Sur Windows Vista et les versions ultérieures du système d’exploitation, DirectSound et waveOut utilisent l’API WASAPI (Windows Audio Session API) pour toutes les sorties audio.
Fragmention de la mémoire virtuelle
Nous avons vu un certain nombre de problèmes récents liés à la limite de 32 bits sur l’espace mémoire du processus. Alors que 2 Go d’espace d’adressage virtuel pour les processus en mode utilisateur ont été plus que suffisants historiquement, l’utilisation accrue de fichiers mappés en mémoire volumineux, d’allocateurs de mémoire personnalisés et l’augmentation de la taille de VRAM (qui doit être mappée dans l’espace de processus) a commencé à entraîner des situations où l’allocation de l’espace mémoire virtuelle échoue. Certaines DLL non-Microsoft utilisent des emplacements à démarrage fixe au milieu de l’espace d’adressage virtuel, ce qui provoque une fragmentation qui entraîne l’échec des allocations.
Ces problèmes apparaissent le plus souvent lorsque le jeu utilise un schéma d’allocation de mémoire personnalisé qui tente d’allouer une grande partie continue de l’espace mémoire virtuel. Nous vous recommandons d’écrire des allocateurs de sorte qu’ils demandent des parties plus raisonnablement dimensionnées de l’espace d’adressage virtuel en fonction des besoins. Par exemple, demander 64 ou 256 Mo à la fois, mais pas 1 Go. Toutefois, il faut veiller à ne pas entraîner de fragmentation supplémentaire. L’avènement des systèmes d’exploitation et du matériel 64 bits aidera grandement ces problèmes à l’avenir, mais il faut faire attention aux systèmes 32 bits de génération actuelle.
Manipulation du Word de contrôle Floating-Point
Pour faciliter le débogage, certains développeurs ont activé des exceptions sur l’unité à virgule flottante (FPU) via des manipulations du mot de contrôle à virgule flottante. Cette opération est très problématique et risque d’entraîner le blocage du processus. Tout comme la convention d’appel exige que le registre ebx soit conservé, la majorité du système suppose que le FPU est dans un état par défaut, donne des résultats raisonnables et ne génère pas d’exceptions. Les pilotes et d’autres composants système calculent souvent les résultats en fonction de l’hypothèse que des valeurs d’erreur standard apparaîtront dans les registres pour les mauvaises conditions, mais si des exceptions sont activées, celles-ci ne seront pas gérées et entraînent des incidents.
Direct3D définit l’unité à virgule flottante sur une précision unique, arrondie à près dans le cadre de l’initialisation du thread appelant, sauf si l’indicateur D3DCREATE_FPU_PRESERVE est utilisé, auquel cas le mot de contrôle à virgule flottante n’est pas modifié. Étant donné que le mot de contrôle est un paramètre par thread, vous assurer que tous vos threads d’application sont définis en mode de précision unique peut optimiser les performances. N’oubliez pas que l’appel de _control87 n’est pas valide pour le codage natif x64, qui utilise exclusivement SSE à la place, et qu’il est extrêmement coûteux sur l’architecture Basée sur PowerPC du processeur Xbox 360.
Notes
Si vous modifiez le mot de contrôle, utilisez _controlfp_s et n’oubliez pas que pour les plateformes x64, vous ne pouvez pas modifier la précision à virgule flottante via le mot de contrôle.
Dans toutes les bibliothèques où nous devons avoir des règles d’arrondi différentes ou d’autres comportements ( comme le traitement des nuanceurs de vertex logiciels ou la compilation), nous enregistrons et restaurez le mot de contrôle. Si un jeu doit utiliser des exceptions d’arrondi ou de FPU non standard, il doit enregistrer et restaurer le mot de contrôle à virgule flottante, et vous devez être sûr qu’il n’appelle aucun code externe qui n’a pas été prouvé pour être protégé contre ces problèmes, y compris les API système.
Installation facultative du runtime DirectX
Un certain nombre de jeux demandent à l’utilisateur s’il faut installer DirectX. Cela peut entraîner des problèmes si l’utilisateur part du principe que le dernier redistribuable DirectX est installé sur le système et ignore l’installation, puis que l’installation se poursuit correctement. Si le jeu nécessite une version spécifique de D3DX ou d’autres fonctionnalités mises à jour qui n’ont pas été installées, le jeu ne fonctionnera pas et l’utilisateur sera très frustré.
Il est vivement recommandé que le programme d’installation du jeu installe silencieusement le redistribuable DirectX sur lequel le jeu a été créé. Le processus d’installation de DirectX est conçu de sorte qu’il vérifie si quelque chose doit être mis à jour et retourne rapidement si ce n’est pas le cas. Il n’est donc pas nécessaire de demander à l’utilisateur l’installation de DirectX.
Une installation sans assistance de DirectX peut être effectuée en exécutant cette commande à partir de votre package d’installation : dxsetup.exe /silent
En outre, la taille réelle du dossier redistribuable peut être configurée pour inclure uniquement les fichiers d’armoire (.cab) qui sont réellement nécessaires pour les plateformes cibles et l’utilisation du jeu.
Notes
Avant d’utiliser dxsetup, lisez Installation pas si directe.
Utilisation excessive de la synchronisation de threads
Lors du profilage des jeux, les principaux points d’accès sont souvent liés à l’entrée et à la sortie de sections critiques. Avec la prévalence des processeurs multicœurs, l’utilisation du multithreading dans les jeux a considérablement augmenté, et de nombreuses implémentations reposent sur une utilisation intensive de la synchronisation de threads. Le temps processeur nécessaire pour prendre une section critique, même sans contention, est assez important, et toutes les autres formes de synchronisation de threads sont encore plus coûteuses. Il faut donc veiller à minimiser l’utilisation de ces primitives.
Une source courante de synchronisation excessive dans les jeux est l’utilisation de D3DCREATE_MULTITHREADED. Cet indicateur, tout en rendant les threads Direct3D sécurisés pour le rendu à partir de plusieurs threads, adopte une approche très conservatrice, ce qui entraîne une surcharge de synchronisation élevée. Les jeux doivent éviter ce drapeau. Au lieu de cela, concevez le moteur de sorte que toutes les communications avec Direct3D proviennent d’un seul thread et que toute communication entre les threads soit gérée directement. Pour plus d’informations sur la conception de jeux multithreads, consultez l’article Codage pour plusieurs cœurs sur Xbox 360 et Microsoft Windows.
Utilisation de RDTSC
L’utilisation de l’instruction x86 RDTSC n’est pas recommandée. RDTSC ne parvient pas à calculer correctement le minutage sur certains schémas de gestion de l’alimentation qui modifient dynamiquement la fréquence du processeur et sur de nombreux processeurs multicœurs pour lesquels le compteur de cycle n’est pas synchronisé entre les cœurs. Les jeux doivent plutôt utiliser l’API QueryPerformanceCounter . Pour plus d’informations sur les problèmes liés à RDTSC et à l’implémentation du minutage haute résolution avec QueryPerformanceCounter, consultez l’article Minutage des jeux et processeurs multicœurs.