Outils pour utilisateurs

Outils du site


back2root:tutoriaux:assembler-tips

Assembler tips

Remplacer MUL par du bit-shift (SHDL)

Quand on fait des démos, il arrive souvent que l'on doive multiplier les y par la taille d'une ligne et ensuite d'y ajouter la valeur de x.

  int offset = (320*y)+x;

ce qui se traduit en assembleur par quelque chose du genre:

        ;              Cycles : 386 | 486
        mov    ax,[y]         ;  4  |  1
        mov    bx,320         ;  2  |  1
        mul    bx             ; 22  | 26
        add    ax,[x]         ;  6  |  1
        ;               Total = 34  | 29

sauf que… cela prends du temps:

Si, sur un 386, un mov prends relativement peu de temps (~ 4 cycles d'horloge) et un add (~2 cycles), un mul est BEAUCOUP plus couteux (jusqu'à 22 cycles sur un 386sx).

on le voit, le 486 est plus optimisé pour les fonctions mov et add, mais le mul est encore plus lourd; heureusement que les 486 sont généralement plus rapide que les 386.

alors qu'un 386 dispose d'instructions simples mais puissantes shld/shrd qui ne demandent que 3 cycles pour s'executer.

on peut donc ré-écrire le code 'c':

  int offset = (y<<6)+(y<<8)+x;

le code précédent peut donc s'écrire:

        ;              Cycles : 386 | 486
        mov    ax,[y]         ;  4  |  1
        mov    bx,ax          ;  2  |  1
        xor    dx,dx          ;  2  |  1
        shld   ax,dx,6        ;  3  |  2
        shld   bx,dx,8        ;  3  |  2 
        add    ax,bx          ;  3  |  1 
        add    ax,[x]         ;  6  |  2
        ;               Total = 21  | 10

on “gagne” presque 40% du temps sur un 386, et 65% sur un 486; ce sont des gains énormes, surtout quand on calcule la position (offset) de centaines de points par frame.

si vous désirez, avoir une résolution différentes, et tant que vous êtes en chained mode (càd que un octet représente un point directement dans la mémoire), vous pouvez utiliser cette fonction; il faut “juste” adapter les shift values:

mul bitshift
80 (y«6)+(y«4)
320 (y«6)+(y«8)
640 (y«9)+(y«7)

back2root/tutoriaux/assembler-tips.txt · Dernière modification : 2024/11/12 14:40 de frater