Canalblog
Suivre ce blog Administration + Créer mon blog

dev jeux web

3 août 2009

optimiser les calculs d'entiers avec les opérations sur les bits

traduction de l'article: http://lab.polygonal.de/2007/05/10/bitwise-gems-fast-integer-math/

Les opérateurs bitwise sont très rapides en AS3, alors voilà une petite collection d'optimisations de calculs. Je n'expliquerai pas ce que sont les opérateurs de bits et comment s'en servir, je préfère linker un excellent article hébergé sur gamedev.net: ‘Bitwise Operations in C’.

Si vous connaissez d'autres astuces qui ne sont pas listées ici, vous pouvez les ajouter par commentaires. Tous les tests de rapidité ont été faits en AS3.

Decalage de bit à gauche pour multiplier par une puissance de deux

Environ 300% plus rapide.

x = x * 2;
x
= x * 64;

//equivaut à:
x
= x << 1;
x
= x << 6;

Decalage de bit à droite pour diviser par une puissance de deux

Environ 350% plus rapide.

x = x / 2;
x
= x / 64;

//équivaut à:
x
= x >> 1;
x
= x >> 6;

Opérateur AND pour modulo par une puissance de deux

reste = numérateur & (diviseur - 1);
C'est environ 600% plus rapide.

x = 131 % 4;

//équivaut à:
x
= 131 & (4 - 1);


Extraire les canaux de couleur

Pas vraiment une astuce, la méthode régulière pour consulter les canaux rouge vert bleu alpha.

//24bit
var color:uint = 0x336699;
var r:uint = color >> 16;
var g:uint = color >> 8 & 0xFF;
var b:uint = color & 0xFF;

//32bit
var color:uint = 0xff336699;
var a:uint = color >>> 24;
var r:uint = color >>> 16 & 0xFF;
var g:uint = color >>> 8 & 0xFF;
var b:uint = color & 0xFF;

Combiner les canaux de couleur

Décaler les valeurs aux bonnes positions et les combiner avec l'operateur bit or ( | ).

//24bit
var r:uint = 0x33;
var g:uint = 0x66;
var b:uint = 0x99;
var color:uint = r << 16 | g << 8 | b;

//32bit
var a:uint = 0xff;
var r:uint = 0x33;
var g:uint = 0x66;
var b:uint = 0x99;
var color:uint = a << 24 | r << 16 | g << 8 | b;

Echanger deux entiers sans passer par une variable temporaire

20% plus rapide

var t:int = a;
a
= b;
b
= t;

//équivaut à:
a
^= b;
b
^= a;
a
^= b;

Changer le signe d'un entier signé

Etrangement c'est 300%(!) plus rapide.

i = -i;

//équivaut à
i
= ~i + 1;

//ou
i
= (i ^ -1) + 1;

Regarder si un entier est pair / impair avec l'opérateur AND

C'est 600% plus rapide.

pair = ((i % 2) == 0) ;

//équivaut à:
pair
= ((i & 1) == 0) ;

Valeur absolue

Oubliez Math.abs() pour le code critique en consommation cpu. La version 1 est 2500% plus rapide que Math.abs(), et la version version 2 est encore 20% plus rapide que la version 1.

//version 1
i
= x < 0 ? -x : x;

//version 2
i
= (x ^ (x >> 31)) - (x >> 31);

Comparer deux entiers pour savoir s'ils sont du même signe

C'est 35% plus rapide.

memeSigne = (a * b > 0);

//équivaut à:
memeSigne
= (a ^ b >= 0);

Conversion rapide de couleur R5G5B5 en format R8G8B8 avec les décalages

R8 = (R5 << 3) | (R5 >> 2)
G8
= (R5 << 3) | (R5 >> 2)
B8
= (R5 << 3) | (R5 >> 2)



Rajout personnel, astuce découverte après étude d'un classique en open-source:


Appliquer la rapidité des integers à des nombres décimaux

Il suffit pour cela d'encoder les nombres décimaux sur des integer de 32 bit.
Par exemple, on prend 16 bits pour coder la partie entière et 16 bits restants pour la partie décimale.

Très utile pour encoder des maps vectorielles 2d ou 3d sans utiliser de float.
Les calculs d'affichage et de collision reposant intégralement sur l'encodage des points, le gain de vitesse est très significatif (calculs avec integer 300% plus rapides qu'avec float).


Pour convertir le nombre décimal 64bit en pseudo-décimal 32bit:

intDecimal = int( floatDecimal * ( 1 << 16 ) )

Pour retrouver la valeur décimale une fois les calculs effectués:

floatDecimal = intDecimal / ( 1 << 16 )
Publicité
Publicité
3 août 2009

unity3d

J'ai pris le temps de tester le trial de Unity3d pour étudier ce moteur, a première vue il me parait plus stable et optimisé que shockwave3d.

Bons points:

- rendu fluide avec vsync fenêtrée
- script c# exécuté par mono, beaucoup plus rapide que les script traditionnels
- possibilité de coder le script en langage boo et javascript
- nombreux effets de shaders prêts à l'emploi

Mauvais points:

- gestion opaque et bizzare de la ram, consommation mémoire importante
- la plupart des effets spéciaux demandent des bonnes cartes vidéo
- contrôle délicat du moteur physique
- incertitude quand à l'avenir du moteur, coûteux à mettre à jour sur les nouveaux os et cartes

Publicité
Publicité
dev jeux web
Publicité
Publicité