Donc j'essaie essentiellement d'implémenter une extension native AIR qui fait la simulation physique en C avec des interfaces via Actionscript.Threading Box2D avec pthreads
Je suis passé par plusieurs itérations que je vais énumérer ci-dessous pour l'intérêt de l'intérêt et je suis à ce que je pense que pourrait être ma dernière tentative pour que cela fonctionne d'une manière plus performante. En fin de compte, je cherche de l'aide dans la façon dont je devrais mettre en place un environnement de threading pour exécuter la simulation de Box2D sur un thread séparé, puis interroger l'état dans AS3.
Méthodes:
- Brute Force:
Dans cette méthode, j'appelle simplement en C de AS3 et lui dire de créer un monde et passer quelques boîtes à ajouter ce monde. Chaque image dans AS3, j'appelle C pour dire au monde de faire un pas, puis faire une boucle sur tous les corps du monde, obtenir leur position et leur rotation, les convertir en objets actionscript et les placer dans un tableau d'actionscript, puis renvoyer AS3. Une fois là-bas, je fais une boucle sur le tableau retourné et j'assigne ces valeurs de position et de rotation à mes sprites afin qu'elles se mettent à jour visuellement.
Les résultats sont en fait assez décent avec environ 116 boîtes ajoutées avant que le framerate ne souffre. Ceci est comparé à 30 boîtes dans une implémentation AS3 pure. Notez que ces statistiques sont en mode débogage. En mode release, ils font tous les deux environ 120 boîtes. Il y a peu de différence entre l'implémentation AS3 et l'implémentation Native Extension.
- ByteArray Partage
Afin d'améliorer les performances, j'ai décidé que ce serait une bonne idée d'essayer de limiter la quantité de données mobilisées dans C et AS3 . Le support d'ANE partageant l'espace mémoire d'un tableau d'octets et donc j'enverrais le ByteArray créé dans AS3 en C et je ferais simplement mettre à jour le ByteArray. Cela nous évite d'avoir à construire des objets AS3 en C et de les renvoyer. A chaque trame, AS3 doit simplement parcourir son ByteArray et voir ce que C a écrit dedans, puis assigner ces valeurs aux sprites pour définir l'état visuel.
Les résultats ici sont malheureusement à peu près les mêmes. Les améliorations ne sont que marginales.
- Réglage objet direct depuis C
est une autre chose ANE sont capables de se définir la propriété d'un objet qui vit en AS3. Dans ce sens, je visais à éliminer le surcoût de renvoi de données à AS3, la boucle à travers les corps pour collecter des données dans C et la boucle dans AS3 pour assigner les valeurs. J'ai directement modifié le code Box2D de sorte que lorsque les valeurs étaient modifiées, il écrivait les nouvelles valeurs de rotation x, y, directement sur le Sprite correspondant.
Les résultats sont étonnants pour de très faibles quantités d'objets puisque l'appel pour définir ces propriétés est bien inférieur à une milliseconde. Le problème est que ceci évolue linéairement et qu'il y a environ 90 objets, les frais généraux sont trop élevés et les choses commencent à ralentir.
- Threading
À ce stade, j'étais un peu perplexe. Il y a un surcoût dans les données de marshalling, il y a un coût en C pour l'itération et la construction des données à retourner et il y a un coût dans AS3 pour l'itération d'assigner des valeurs aux sprites.
Évidemment, il doit y avoir un compromis de sorte que ma solution actuelle est la meilleure que je peux trouver pour l'instant. Du côté AS3, vous appelez C pour créer votre monde, appelez pour ajouter une boîte à ce monde, et appelez pour dire à C que vous voulez un rafraîchissement de vos données. Lorsque les boîtes sont créées dans AS3, elles reçoivent un identifiant unique et sont stockées dans un dictionnaire dont la clé est l'identifiant. Sur le côté C, le monde est créé et un nouveau pthread est créé pour faire le Step. Essentiellement simulant le monde sur un autre fil. Après l'étape, il rassemble toutes les données et les écrit dans un double tableau. Ensuite, il le fait encore et encore et encore. Il simule simplement pour toujours sur son propre fil.
Lorsque nous appelons C pour ajouter une nouvelle boîte, je dois créer une nouvelle boîte et l'ajouter à ce monde. Puisque le monde est en marche, cela pourrait causer des problèmes, ce qui signifie que je dois utiliser des mutex. Même chose quand nous appelons pour obtenir les valeurs rafraichies dans AIR, je veux faire un memcpy de la matrice de doubles dans mon bytearray AS3 et ensuite faire une boucle dans le bytearray pour définir les valeurs sur le visuel.
Les mutex me donnaient du mal donc je essentiellement mis en œuvre ma propre que vous pouvez voir ci-dessous ... et rire :)
Cependant, il fonctionne, mais pas aussi vite que je le voudrais aussi. Vers 90, nous ralentissons à nouveau.
Quelqu'un at-il des idées ou des pointeurs? Ce serait grandement apprécié!
Code C
L'analyseur a agi de façon à ce que j'ai collé ici: http://pastebin.com/eBQGuGJX
Code AS3
Même chose avec l'analyseur. J'ai seulement inclus la méthode pertinente traitant de chaque image dans AS3. http://pastebin.com/R1Qs2Tyt
J'ai le sentiment saigne bord assez que vous ne trouverez pas beaucoup d'aide partout :) Je suis aussi perplexe pourquoi les discussions contribueraient. Puisque chaque étape du monde a besoin des informations de la dernière étape, elles ne peuvent pas être exécutées en parallèle, et l'exécution de la partie C dans un thread propre n'aide pas si le goulot d'étranglement est le transfert d'informations vers AS3. Dans une étape mondiale, il est possible de faire de petites sections du processus simultanément, mais le gain de performance est assez faible et le consensus général semble être qu'il est plus avantageux d'utiliser des cœurs supplémentaires pour le rendu ou autre chose. – iforce2d
Merci iforce2d. Ouais je n'étais pas sûr d'avoir une réponse en soi, mais j'espérais potentiellement approfondir la discussion sur des approches comme celle-ci ou des liens vers des documents pertinents pour des explications plus approfondies. Mon espoir était que la simulation puisse être juste en cours d'exécution sur son propre thread et que le rendu apparaîtrait juste et tirerait le dernier "snapshot" des positions d'objet et l'utiliserait pour le rendu. – Jon
+1 pour une question/article très intéressant – Ryan