[ASM] Optim : précalcul en mémoire ou calcul sur registres ?

Optim : précalcul en mémoire ou calcul sur registres ? [ASM] - ASM - Programmation

Marsh Posté le 03-08-2004 à 22:38:37    

Il me faudrait un algo optimisé Pentium et pas plus, donc pas de prefetch etc...
J'ai déjà un truc mieux pour PMMX et plus
 
J'ai un unsigned byte représentant un pixel niveau de gris, notons le Y
Je doit générer un dword 0:Y:Y:Y (1 octet 0 poids fort et 3 octets Y)
 
Qu'est ce qui est le plus rapide ?
Précalculer ça pour Y = 0 à 255 et mettre ça (256 * 4 = 1Ko) en mémoire .const ou regénrer le dword avec les registres :
 

Code :
  1. xor eax, eax       ; 0:0:0:0
  2. mov al, Y          ; 0:0:0:Y
  3. mov ah, al         ; 0:0:Y:Y
  4. shl eax, 8         ; 0:Y:Y:0
  5. mov al, ah         ; 0:Y:Y:Y

   
 
Lequel est le + rapide ?
J'ai la flemme de coder un bench et je voudrais savoir si en général il vaut mieux précalculer ce genre de truc. Des valeurs très complexes à calculer ok, mais là juste 5 instructions, surtout que en en calculant un deuxième avec ebx c'est bien pipelinable.

Reply

Marsh Posté le 03-08-2004 à 22:38:37   

Reply

Marsh Posté le 04-08-2004 à 14:00:54    

Tout dépends de ce qu'il y a autour.
Le code est-il dans une boucle ?
S'il y a 1Ko de pris dans le cache, cela va-t-il poser un problème ?
 
En général une LUT est plus rapide dans une boucle, mais tout dépend de la taille du cache L1 et des données déjà dans le L1.
 
En général sur Athlon, c'est plus rapide, mais sur P4, c'est plus lent (le cache L1 est plus petit).
 
Ensuite, il peut être plus interressant de faire ceci :
(Si on est dans L1, avec X et Y)


mov al, X
mov bl, Y
and eax, 255
and ebx, 255
mov eax, LUT[eax*4] ;AGI stall (2 à 3 cycles d'attente)
mov ebx, LUT[ebx*4] ;AGI stall (2 à 3 cycles d'attente)


 
Donc on peut dire que ta solution est déjà très bonne.
Mais si on calcule 4 points simultanément, il est possible que la version avec LUT soit plus rapide.

Reply

Marsh Posté le 04-08-2004 à 15:16:49    

Oui c'est bien dans une boucle, il y a en général dans les 100 000 itérations.
Comme dit plus haut ça doit s'éxécuter sur P1 voire mois mais pas plus. 1Ko dans le cache pkoi pas, mais ce code s'éxecute sous Win32 sans contrainte sur le task switching.
 
Pour ton code je crois qu'on peut faire + rapide :
 
xor eax, eax
xor ebx, ebx
 
:debut boucle
 
mov al, X  
mov bl, Y  
mov ecx, LUT[eax*4] ;AGI stall (2 à 3 cycles d'attente)  
mov edx, LUT[ebx*4] ;AGI stall (2 à 3 cycles d'attente)
...
:finboucle
 
j'ai fait un bench avec rdtsc la méthode registre est un poil + rapide que la méthode LUT, mais sur k6-3, j'ai pas de P1 sous la main aujourd'hui. Le rapport était 11 pour 12 donc très proche.

Reply

Marsh Posté le 06-08-2004 à 10:31:55    

En fait, j'ai pris uniquement 1 registre pour le calcul pour que tu puisses traîter 4 points à la fois via la LUT.
A mon avis, c'est là que tu vas y gagner :


preloop:
mov esi, 255
 
loop:
mov al, X  
mov bl, Y
mov cl, U  
mov dl, V  
and eax, esi  
and ebx, esi  
and ecx, esi  
and edx, esi
 
... Mettre du code ici pour masquer les AGI stall
 
mov eax, LUT[eax*4] ;AGI stall (1 à 2 cycles d'attente)  
mov ebx, LUT[ebx*4] ;AGI stall (1 à 2 cycles d'attente)  
mov ecx, LUT[ecx*4] ;AGI stall (1 cycle d'attente)  
mov edx, LUT[edx*4] ;AGI stall (1 cycle d'attente)  


On peut virer mov esi, 255 pour re-gagner ce registre...


Message édité par christophe_d13 le 06-08-2004 à 10:32:45
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed