Posté le: 24/05/11 08:56 Sujet du message: Threads
Je cherche actuellement des informations sur la gestion des threads au niveau des déclencheurs.
Je sais que Wc3 est encore capable d'exécuter du code Jass en parallèle car cela m'est arrivé sur la carte La Course d'Ayane où j'ai dut agencer les déclencheurs différemment. Récemment j'ai cherché à créer des threads afin d'effectuer un traitement de manière parallèle, mais cela a l'air de s'exécuter plutôt de manière sériale, peut être parce que j'appelais certaines fonctions qui exécutaient un verrou (lecture d'une hashtable pour le passage de paramètres).
J'aimerais donc savoir s'il y a des personnes qui disposent d'informations à ce sujet dans le but de pouvoir l'exploiter pour du traitement parallèle. _________________
TriggerEvaluate est plus rapide que TriggerExecute alors qu'il doit en plus vérifier les conditions?
Ainsi si un déclencheur A est en cours d'exécution et qu'un déclencheur B s'exécute entre temps, le déclencheur A se met en pause, exécute B, puis reprend l'exécution de A?
Si c'est le cas le seul avantage que j'ai eu à coder mes traitements pouvant fonctionner en parallèle a été d'éviter la barrière du temps d'exécution d'un déclencheur. _________________
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 24/05/11 18:45 Sujet du message:
Ayane a écrit:
TriggerEvaluate est plus rapide que TriggerExecute alors qu'il doit en plus vérifier les conditions?
En fait c'est devenu un standard de coder dans les conditions de trigger, et ne plus utiliser d'actions de trigger, parce que c'est plus rapide, et en cas de destruction de trigger, nul besoin de supprimer les conditions du trigger, au contraire des actions de trigger.
TriggerClearActions ne faisant que désactiver les actions sans les libérer de la mémoire.
Je ne peux pas expliquer pourquoi c'est plus rapide, mais c'est ainsi.
Evidemment dans une condition de trigger on ne peut pas utiliser TriggerSleepAction et donc PolledWait non plus, mais il est rare de vouloir utiliser un temps qui continue à se découler pendant les pauses du jeu, et comme les timers sont plus précis, même si plus chiants à utiliser.
Cela dit ça n'a pas grande importance pour des triggers qui n'ont pas besoin d'être détruits ou ne sont pas utilisés de façon intensives, et rien ne t'oblige à coder dans une condition de trigger si tu trouves cela aberrant, je ne fais que relater ce qui ce passe désormais.
Citation:
Ainsi si un déclencheur A est en cours d'exécution et qu'un déclencheur B s'exécute entre temps, le déclencheur A se met en pause, exécute B, puis reprend l'exécution de A?
Aussi loin que je connaisse, oui. Jamais expérimenté de thread parallèles, juste en série. J'ai jamais essayé avec un ForForce et plusieurs joueurs cela dit, mais j'y crois pas.
Je me rappelle que tu avait dit que c'était possible avant, mais personnellement j'ai jamais connu.
Citation:
Si c'est le cas le seul avantage que j'ai eu à coder mes traitements pouvant fonctionner en parallèle a été d'éviter la barrière du temps d'exécution d'un déclencheur.
Ouep, enfin je sais pas trop si c'est un nombre d'opérations maximum ou un temps d’exécution maximum, il me semble que c'est plus un nombre (limitop).
Ah, et dans le cas des timers à faible période il est intéressant d'utiliser un seul timer et des conditions de trigger (plus efficace que X timers avec X callbacks), je te conseille de regarder après la library vJass T32 (thehelper.net), comme exemple en tout cas. _________________
Pour le fait de coder dans les conditions j'étais au courant, en fait dans les actions l'exécution est plus complexe comme par exemple le fait qu'il puisse être arrêté pour être repris plus tard. Cela doit créer une instance d'un thread WC3 alors que dans les conditions il exécute le code directement, ce qui implique qu'il ne doit pas pouvoir être mis en pause en codant ainsi. Coder dans les conditions n'est donc pas du tout fait pour ce que je recherche.
Pour le rendu je n'ais qu'un seul déclencheur périodique de 40ms, j'y ais déplacé tous mes codes périodiques en y mettant des pseudo-timers, c'est à dire une variable entière que je décrémente à chaque itération, lorsqu'elle atteind 0 j'exécute le code et je réinitialise la variable. Au début j'avais fait plusieurs déclencheurs mais il arrivait que l'un s'exécute pendant l'exécution de l'autre, tout mettre dans un seul m'a donc permis de régler ce conflit de threads. _________________
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 24/05/11 20:23 Sujet du message:
Ayane a écrit:
Au début j'avais fait plusieurs déclencheurs mais il arrivait que l'un s'exécute pendant l'exécution de l'autre, tout mettre dans un seul m'a donc permis de régler ce conflit de threads.
Hmm, étrange, aurais tu encore le code ? _________________
Ce n'est pas étrange si l'on considère que le déclencheur B a mis en pause le déclencheur A.
Pour le refaire il suffit juste de légèrement modifier ma carte. J'ai eu le problème en fait à deux endroits:
- Le premier consiste en des déclencheurs de lancement, l'une des série d'exécution était ceux de la cinématique donc à la base un déclencheur avec Time Elapsed 0.0 puis un Run sur Scene1 Send Cinematic Text avec l'option Attendre et un Run sur Scene2 qui lui créé deux unités qui sont enregistrées dans le système de physique. La seconde série d'exécution était un déclencheur avec Time Elapsed de 10.65 sec environ, il coïncidait avec le lancement de Scene2 et se charge de lancer la course, donc il fait un Run sur VEH Create qui lui créé les véhicules qu'il ajoute au système physique.
Là où je me suis rendu compte qu'il y avait un problème de thread c'est que normalement les véhicules ont une masse de 100 et les paysans ont une masse de 1 ce qui fait que lorsqu'on les percute on ne le sent pratiquement pas; mais avec cette disposition il arrivait des fois (en relançant la carte cela pouvait être normal) que l'on percute les paysans comme sur un mur, c'est à dire qu'ils avaient une masse assez importante. La seule possibilité étant que la création de véhicule puisse s'exécuter pendant la création des paysans. C'est donc le déclencheur de la Scene2 qui lance les déclencheurs d'initialisation de la course ce qui a réglé le problème.
- Le deuxième était la vérification qu'une unité se trouve dans la lave, toutes les 500ms cela vérifiait si l'unité se trouvait dans la lave et si c'est le cas cela déplaçait l'unité à un checkpoint et réinitialisait plusieurs valeurs, notamment pour mettre à zéro la vélocité du véhicule. Cela annulait également les touches appuyées, variables elles manipuler également par la gestion de l'ordinateur qui s'exécutait également dans un autre périodique (toutes les 250ms). C'était moins visible puisque corrigé par la suite, mais il arrivait que le véhicule une fois téléporté conserve certaines caractéristiques de la trajectoire précédemment calculée, l'ordinateur pouvait donc commencer à partir dans le sens opposé comme si la téléportation n'avait pas annulée ses précédentes données (puis évidemment il corrigeait après sa trajectoire pour suivre le trajet qu'il faut). J'ai donc mis le périodique de l'IA et de la lave dans celui du rendu physique avec des pseudo-timers et cela a résolu tous les problèmes de ce genre qui avait été rencontrés.
Conclusion: les threads de WC3 ne s'exécutent pas forcément parallèlement, en considérant qu'un thread peut être mis en pause pendant son exécution pour laisser l'exécution à un autre thread cela explique tout à fait les phénomènes observés. C'est fort possible étant donné que lors de la sortie de WC3 il n'y avait que très peu de PC multi-CPU (sans parler des systèmes d'exploitations qui ne le gérait pas); sur mono-CPU on considérait que c'était cela le fonctionnement d'un processus: on en exécute une partie puis on le met en pause en sauvegardant les registres et on passe à l'exécution d'un autre processus en chargeant les données correspondant dans les registres. On n'avait pas la même conception de traitement parallèle car ce n'était pas possible à l'époque, il ne s'agissait que d'une émulation qui pouvait faciliter l'algorithme. Il aurait fallut que Blizzard utilise des threads système au lieu de threads software, les systèmes d'exploitations de maintenant aurait permis au Jass de faire du traitement parallèle. _________________
Vous ne pouvez pas poster de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas voter dans les sondages de ce forum