2 votes

Quelle est la bonne architecture pour un simulateur de vie ?

L'autre jour, j'ai pensé à créer un petit simulateur de vie. Je n'ai fait qu'effleurer l'idée et je me demandais quelle était la meilleure façon de la mettre en œuvre pour qu'elle fonctionne efficacement.

Au niveau le plus bas, il y aura des entités mâles et femelles qui se promèneront et qui, lorsqu'elles se rencontreront, produiront une progéniture.

J'aimerais utiliser le multithreading pour gérer les entités mais je ne suis pas sûr du nombre de threads, etc.

Serait-il préférable d'avoir deux threads qui gèrent les mâles et les femelles, ou serait-il possible de démarrer un thread pour chaque entité afin que chaque instance fonctionne sur son propre thread ?

J'ai lu quelques posts sur le nombre maximum de threads et la limite se situe entre 20 et 1000 threads dans une application.

Quelqu'un a-t-il des suggestions sur l'architecture ?

N

15voto

Eric Lippert Points 300275

NE PAS AVOIR UN FIL PAR ENTITÉ . C'est la recette d'un désastre. Les fils n'ont pas été conçus pour cela. Les threads sont extrêmement lourds ; rappelez-vous que chaque thread consomme un million d'octets d'espace d'adressage virtuel immédiatement . N'oubliez pas non plus qu'à chaque fois que deux threads interagissent sur une structure de données partagée (comme votre monde simulé), ils doivent prendre des verrous pour éviter toute corruption. Votre programme sera un masse de centaines de fils bloqués, et les fils bloqués sont inutiles ; ils ne peuvent pas fonctionner. Une forte contention est anathème pour de bonnes performances, et un grand nombre de threads partageant une structure de données n'est rien d'autre qu'une contention constante.

Le nombre de threads dans votre programme doit être de un à moins d'avoir une très bonne raison d'en avoir deux. En général, le nombre de threads dans un programme doit être de aussi petit que possible tout en conservant les caractéristiques de performance dont vous avez besoin.

Si votre programme est réellement "embarrassingly parallel" (c'est-à-dire qu'il est extrêmement facile d'effectuer des calculs en parallèle sans verrouiller une structure de données partagée), le nombre correct de threads est égal au nombre de cœurs de processeur de la machine. N'oubliez pas, les fils se ralentissent mutuellement . Si vous avez quatre guichetiers et que chacun d'entre eux s'occupe d'un client, les choses vont vite. Vous décrivez une situation dans laquelle quatre guichetiers (cœurs d'unité centrale) s'occupent chacun d'une centaine de personnes en même temps en distribuant des centimes à la ronde.

Les simulations sont rarement d'un parallélisme gênant, car il est difficile de diviser le travail en plusieurs étapes. indépendant pièces. Le traçage de rayons, par exemple, est étonnamment parallèle ; le contenu d'un pixel ne dépend pas du contenu d'un autre pixel, de sorte qu'il peut être calculé en parallèle. Mais vous n'auriez pas un thread par pixel ! Vous auriez un thread par processeur, et vous laisseriez chacun des quatre processeurs travailler sur un quart des pixels. Il est difficile de faire cela avec des simulations parce que les entités faire interagir les uns avec les autres.

Les simulateurs professionnels de haute qualité, tels que les moteurs physiques, qui doivent gérer des entités en interaction, ne résolvent pas leurs problèmes avec des fils. En général, ils disposent d'un thread pour effectuer la simulation et d'un autre pour exécuter l'interface utilisateur, de sorte qu'un calcul de simulation coûteux ne bloque pas l'interface utilisateur.

La bonne architecture pour vous est probablement d'avoir un fil de discussion qui tourne à plein régime pour faire la simulation. Travaillez tous les interactions des entités pour une seule image et signale ensuite au fil d'exécution de l'interface utilisateur qu'il doit être mis à jour. Cela vous permettra de déterminer votre fréquence d'images maximale, en mesurant le nombre de microsecondes nécessaires à l'élaboration de toutes les interactions de chaque entité.

1voto

Henk Holterman Points 153608

L'utilisation de centaines de threads (ce qui entraînerait un grand nombre de Sleep()) n'est pas une bonne solution. Vous manquerez rapidement de mémoire.

Le TPL pourrait rendre cette idée réalisable, mais il n'a pas été conçu pour cela non plus.

Examinez la simulation d'événements discrets et les fibres. Il existe des bibliothèques de pseudo-fibres pour .NET.

1voto

Danny Varod Points 8685

Je suppose que votre application gère la ligne du temps en delta-Ts.

Vous pourriez utiliser le cadre parallèle de C# 4.0 et travailler avec des TASKs et non des threads.

Chaque delta-T exécute un for parallèle pour mettre à jour les entités.

Le cadre parallèle décidera du nombre de threads à ouvrir et les gérera.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X