Les gars, je développe une application de jeu multijoueur avec C++ et en train de choisir une architecture multithread appropriée pour elle.C++ multithreading: les verrous explicites dans les classes de modèle de domaine
Le noyau de l'application est la boucle sans fin qui met à jour essentiellement chaque trame toutes les entités du jeu mondial. Actuellement, cette boucle mondiale est singlethreaded. Cela fonctionne très bien mais j'aimerais vraiment le rendre plus évolutif sur les multicœurs.
Comme toutes les entités du monde existent dans les établissements et mis à jour dans chaque trame comme suit:
- World::update(dt) //dt is delta time since the last frame - Location::update(dt) - WorldEntity::update(dt) - WorldEntity::update(dt) - ... - Location::update(dt) - WorldEntity::update(dt)
... Je pensais à l'exécution de chaque emplacement (et sa logique de mise à jour) dans un thread séparé. Cela signifie que j'ai besoin de synchroniser correctement les entités du monde. Et ce que je vraiment ne veux pas faire depuis, je crois, verrouillage explicite dans les classes domaine des méthodes est faux et il fait le développement, le maintien et le débogage très beaucoup plus difficile.
Au début, je pensais à isoler les entités de localisation des entités dans différents endroits en interdisant les appels entre eux. Quels sont les moyens possibles pour y parvenir? Stocker des entités de chaque emplacement dans un stockage local de thread afin qu'ils ne soient pas accessibles de l'extérieur? Ou peut-être à la place d'un thread par emplacement, utilisez plutôt des processus (mais cela compliquera beaucoup). Cependant
même si des entités de localisation sont bien isolées il un autre problème - la persistance. J'ai déjà une sorte de service de persistance générique simple qui s'exécute dans un thread séparé. Il peut être utilisé en mode asynchrone, il accepte un objet à sauvegarder et renvoie un objet futur spécial qui peut être utilisé pour suivre le processus de persistance. J'aimerais utiliser ce service, mais comme il fonctionne dans un thread séparé, je dois de nouveau synchroniser correctement l'accès aux classes de domaine. Dans ce cas, l'option possible pourrait être d'implémenter correctement le clonage des objets de domaine afin que le service de persistance accepte une copie de l'objet à sauvegarder et aucun verrouillage explicite ne serait nécessaire ...
D'où la question, tout est dit ci-dessus en vaut la peine? Ou peut-être devrais-je simplement ajouter une logique de synchronisation explicite dans toutes les classes de domaine et en finir avec elle? Ou peut-être y a-t-il une meilleure option dont je ne suis pas au courant?
Merci à l'avance
Mise à jour ajouté schéma de structure mondiale grâce à Jed Smith
Pouvez-vous visualiser la structure de votre code? Et des interactions entre chaque étapes et fonctions. Le plus important est de trouver des parallélismes dans votre code. Aussi, s'il vous plaît mettez '' pour certains termes comme "World", "Location". Vous voulez paralléliser une grosse boucle. Si la boucle n'a pas de "dépendances bouclées", alors c'est très facile. Cependant, dans votre cas, ce n'est pas le cas. Ensuite, le «parallélisme pipeline» pourrait être mis en œuvre. Oui, je sais qu'il y a des mots à la mode, que vous n'êtes peut-être pas familiers. Mais, il s'agit d'une stratégie générale sur la pararllisation au niveau de la boucle. – minjang
Quel est le meilleur pour le faire ici? En éditant le message original ou en me répondant à moi-même? – pachanga
Oh merci, je l'ai eu. Vous devez également vérifier les "dépendances". Par exemple, WorldEntity :: update a-t-il des dépendances avec l'appel précédent? Qu'en est-il des emplacements? La compréhension des dépendances est la première étape de la parallélisation. – minjang