J'ai fait des recherches sur la création de mes propres méthodes d'allocation (qui prendront en charge des éléments tels qu'un pool de mémoire et le profilage), cependant, alors que je continue mes recherches, j'ai cherché comment cela a été fait dans le développement de jeux.
Quelle technique d'allocation de mémoire puis-je utiliser et pourquoi est-ce une bonne technique?
Réponses:
Game Engine Architecture contient des informations sur ce sujet. Les bases sont que vous devez faire une analyse pour comprendre vos besoins en mémoire par niveau / trame / etc. sont comme, mais il y a quelques modèles que l'auteur mentionne avoir vu plusieurs fois:
La plus grande chose que l'auteur mentionne est la fragmentation de la mémoire. C'est moins un problème si vous développez par exemple pour un PC où vous avez une sorte de sauvegarde de pagination de la mémoire sur laquelle vous pouvez compter, mais dans un contexte de mémoire fixe comme une console, il y a le risque d'être "à court de mémoire" lorsque vous essayez d'allouer pour un grand objet car votre mémoire est fragmentée de telle sorte que seuls de petits blocs contigus sont disponibles. À cette fin, il recommande qu'un allocateur basé sur la pile comme ci-dessus inclue également une méthode de défragmentation périodique de son contenu.
Pour plus d'informations sur le code réel impliqué dans cela, je recommande fortement l'article de Christian Gyrling, "Sommes-nous à court de mémoire?" , qui couvre les techniques d'allocateurs personnalisés, principalement du point de vue de l'analyse des modèles d'utilisation de la mémoire, mais cela s'applique également à la conception d'une solution personnalisée pour la gestion de la mémoire.
la source
D'après ce que j'ai vu (mais pas fait), chaque jeu a tendance à hériter des mécanismes d'allocation d'un framework, d'un moteur de jeu, de la version précédente (2010 -> 2011) ou il obtient un ensemble de nouveaux écrits spécifiquement pour son (lorsque les structures de données sont réutilisables et de taille fixe ou de nombreux types et tailles variables).
Nous avions également des allocateurs différents pour les fichiers / composants sonores que pour les niveaux et autres objets de jeu dans le même projet. Dans d'autres projets, les allocateurs sont hérités des bibliothèques externes uniquement pour les composants gérés par cette bibliothèque.
L'optimisation dépend vraiment de vos besoins. Mais généralement, l'allocation est effectuée avant d'entrer sur la scène du jeu, puis la mémoire est réutilisée. Certains jeux peuvent s'en tirer sans avoir d'allocateurs personnalisés. Mais pour les jeux d'action où le processeur, la mémoire et les ressources de données sont budgétisés, vous ne pouvez pas vous permettre de perdre du temps de traitement sur de grandes allocations, vous ne pouvez pas gaspiller la mémoire en fragmentation et autres problèmes.
Concernant les exemples, vous devriez simplement commencer par jeter un œil au moteur de jeu OGRE 3D , il a quelques options pour configurer les allocateurs de mémoire.
la source
L'erreur qui est souvent commise est d'écrire vos propres allocateurs afin que vous puissiez avoir plus de contrôle sur la quantité de mémoire utilisée par chaque système et avoir plus de visibilité sur ce qui se passe. Un bien meilleur moyen d'y parvenir est d'utiliser un profileur de mémoire. Il existe de nombreux profileurs de mémoire, mon profileur MemPro en est un exemple. Il s'agit d'un moyen totalement non invasif de garder une trace de toute l'utilisation de la mémoire et vous pouvez la décomposer automatiquement en sous-systèmes à l'aide de filtres génériques de pile d'appels. Idéalement, il est préférable de garder votre allocation de mémoire et votre suivi de la mémoire totalement séparés, ils ont des exigences totalement différentes.
Diviser arbitrairement votre mémoire en pools peut souvent être préjudiciable car chaque pool aura un surcoût. Vous pouvez finir par utiliser beaucoup plus de mémoire que nécessaire sans vous en rendre compte. Pour réduire le gaspillage, il est toujours préférable de tout regrouper, le jeu est alors partagé par l'ensemble du système.
Les seules raisons d'utiliser des allocateurs personnalisés sont les performances du processeur (principalement pour la cohérence du cache) et pour limiter la fragmentation. Un exemple parfait de ceci est un système de particules. Vous voulez toutes les particules contiguës en mémoire et vous ne voulez pas poivrer la mémoire principale avec beaucoup d'allocations de courte durée. Un autre bon exemple de partitionnement est un langage de script.
Si vous voulez un exemple de remplacement de malloc à usage général, vous pouvez jeter un œil à mon allocateur VMem . Il a été utilisé dans un certain nombre de jeux AAA livrés. Il dispose de techniques qui limitent la fragmentation et maintiennent une empreinte mémoire faible, ce qui est essentiel pour les jeux sur console. Il est également très rapide sous forte contention de threads. Mon site Web contient une documentation complète sur ces techniques.
la source