AS3 Concurrency/Workers : using shared ByteArray and Mutex

Hello there,
je vais vous parler un peu des Workers récemment implémentés au Flash Player 11.4.
Autant vous le dire tout de suite, vous ne pouvez pas passer à coté de cette nouvelle classe.
Chaque Workers utilise une instance de la machine virtuelle (MV) du player Flash (FP) qui s’exĂ©cute en background de votre application.

L’intĂ©rĂȘt est donc de faire tourner du code en arriĂšre plan pour allĂ©ger la MV principale, celle qui affiche votre application.
Il est bien sûr possible de communiquer entre les différents Workers de différentes maniÚres :
- en envoyant des messages via MessageChannel.send()
- en partageant un ByteArray (BA) (depuis le FP 11.5) dont l’instance sera accessible par tous les Workers.

La mĂ©thode du BA est particuliĂšrement puissante puisse qu’il suffit de modifier l’instance du BA
pour que les Workers aient accÚs aux nouvelles données dans un Event enterframe par exemple.

PROBLÈME : il est possible qu’un Worker cherche Ă  lire ou modifier le BA alors qu’un autre Worker est en train de le lire ou de le modifier… on est en multitĂąche donc c’est logique.

//dans un Worker…

ba.position=0;
ba.writeInt(12);
ba.writeFloat(12.5);
ba.writeInt(5);

donc le BA contient 12,12.5,5
sauf qu’apres ba.writeInt(12); un Worker a essayĂ© de lire les donnĂ©es…

ba.position=0;
n=ba.readInt();
f=ba.readFloat();
n=ba.readInt();

le pointeur ayant été remit à zéro, on se retrouve avec des données corrompues.

Ce cas de figure arrive en général quand le Worker qui modifie le BA mets énormément de temps à le mettre à jour.

Il est possible d’empĂȘcher ce problĂšme en utilisant la class Mutex,
c’est un peu l’équivalent d’un feu rouge, avant de modifier/lire le BA on lock l’instance du Mutex
quand on a fini on unlock le mutex.
Si on essaye de lire le BA alors que le mutex est locké, la VM se mets en pause et attend que le Mutex soit unlocké pour se relancer.
Il est donc impossible de Ă©diter/lire le BA alors qu’un Worker est entrain de l’éditer/lire.

PROBLÈME: (raaahhhhhh tout ce passait si bien pourquoi ?!!!)
Si votre Background Worker mets du temps Ă  mettre Ă  jour votre BA (genre 40ms alors que votre budget par frame est de 33ms) le FPS de votre main Worker baisse.
Normal, vous essayez de lire le BA dans votre Main Worker, Mutex mets en pause la VM le temps que le Mutex soit unlocked.

Donc dans ce cas de figure le main Worker se retrouve avec autant de FPS que le Worker en background (celui qui mets du temps Ă  Ă©diter le BA).

Mutex c’est gĂ©nial mais c’est donc Ă  utiliser pour des cas trĂšs particulier.

NB: Notez qu’il existe aussi la mĂ©thode tryLock() qui bloque le Mutex sur le current Worker s’il n’est pas dĂ©jĂ  bloquĂ© et renvoi true, ou juste false si le Mutex est bloquĂ© sur un Worker.
Contrairement Ă  lock, tryLock ne bloque pas la MV, le code continuera Ă  s’exĂ©cuter normalement.

Et maintenant la pratique avec 3 tests:
(FP11.5 requis, les démos ne fonctionne pas sous chrome? about:plugins vous devez avoir plusieurs plugins flash activé, désactivez celui situé dans les répertoires de chrome )
sourcecode du worker Mutex (echapez mutex.lock/unlock pour ne pas utiliser Mutex)

J’ai volontairement augmentĂ© la charge dans le Worker qui gĂšre la physique afin qu’on puisse voir le FPS Ă©voluer:

//dans l'update de chaque particules
var l:int=300;//oh le bourrin !
while(l--){
	velocity.x=Math.cos(_angle*Math.PI/180)*speed;
	velocity.y=Math.sin(_angle*Math.PI/180)*speed;
}

-un test qui n’utilise pas de Worker,
au bout d’un certain temps ça rame comme prĂ©vu…

-un test qui utilise des Workers (un pour la vue et l’autre pour la physique) et shared BA
le Worker qui gĂšre la physique perd du FPS mais pas le main Worker donc cool !
Par contre l’accĂšs au BA n’est pas contrĂŽlĂ© par Mutex donc risque de donnĂ©es corrompues.

-un test qui utilise des Workers, shared BA et Mutex
le Worker qui gĂšre la physique perd du FPS et entraine dans sa chute le FPS du main Worker :/

  1. Aucun commentaire pour l'instant

  1. Aucun trackback pour l'instant