Déroulage de boucles et aléas

Déroulage de boucles et aléas - ASM - Programmation

Marsh Posté le 26-08-2005 à 11:47:52    

Bonjour à tous,
 
 
J'ai un petit problème de compréhension sur certaines choses en Assembleur. En effet j'ai étudié l'Assembleur DLX et j'ai quelques notions qui me posent problème.
 
Tout d'abord, je ne comprends pas l'intérêt du "déroulage de boucle" ? De plus de façon générale, comment distinguer efficacement les différents types d'aléas au sein d'un code assembleur afin d'en améliorer l'exécution ?
 
Ceci étant purement à but d'apprentissage :)
 
Merci d'avance !

Reply

Marsh Posté le 26-08-2005 à 11:47:52   

Reply

Marsh Posté le 26-08-2005 à 13:01:53    

le déroulage de boucle te permet d'éviter les instructions de saut. sur des grosses boucles, ça procure un gain assez significatif


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 26-08-2005 à 13:44:54    

Merci pour ta réponse :) Quelles sont les méthodes principales pour dérouler une boucle ?

Reply

Marsh Posté le 26-08-2005 à 14:47:48    

recopier chaque itération de la boucle linérairement dans le code


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 26-08-2005 à 15:30:50    

Ok merci c'est bien ce que je pensais aussi.  
 
D'un point de vue théorique, on parle de réordonnancer le code pour éviter les différents aléas (Lecture après Ecriture ...) et ainsi permettre d'éviter des cycles de latence.  
 
Y aurait t-il une technique pour repérer ces problèmes rapidement ?  
 

Reply

Marsh Posté le 26-08-2005 à 15:37:02    

utiliser un profiler de code peut-être

Reply

Marsh Posté le 26-08-2005 à 16:16:12    

En fait c'est sur le plan purement théorique, c'est pour des révisions que je me renseigne car c'est du code sur papier :(

Reply

Marsh Posté le 04-09-2005 à 09:00:08    

Sur le plan purement théorique (et pratique)
- Le saut vide le pipe.
- L'AGI stall recommence à zéro.
 
l'exemple simple...

Code :
  1. loop:
  2. mov eax, [ebx+esi]
  3. ...
  4. sub esi, 4
  5. jnz loop


 
Dans cet exemple, on va avoir un AGI stall sur mov eax, [esi+ebx] Sa durée est de 2 à 3 cycles (parfois plus suivant la distance à laquelle se trouve la donnée).
 
 
Le fait de dérouler une boucle permet de multipler la vitesse dans des cas utilisant la mémoire de façon linéaire et intensive (FFT, copy, transfert, échange) :

Code :
  1. loop:
  2. movq mm0, [esi+eax]
  3. movq mm1, [esi+eax+8]
  4. movq [edi+eax+8], mm0
  5. movq [edi+eax], mm1
  6. add eax, 16
  7. js loop


Si on déroule...

Code :
  1. loop:
  2. movq mm0, [esi+eax]
  3. movq mm4, [esi+eax+32]
  4. movq mm2, [esi+eax+16]
  5. movq mm6, [esi+eax+48]
  6. movq mm1, [esi+eax+8]
  7. movq mm5, [esi+eax+40]
  8. movq mm3, [esi+eax+24]
  9. movq mm7, [esi+eax+56]
  10. movq [edi+eax],    mm1
  11. movq [edi+eax+8],  mm0
  12. movq [edi+eax+16], mm3
  13. movq [edi+eax+24], mm2
  14. ...
  15. movq [edi+eax+56], mm6
  16. add eax, 64
  17. js loop


Message édité par christophe_d13 le 06-09-2005 à 10:59:03

---------------
http://www.ikalizer.fr
Reply

Marsh Posté le 04-09-2005 à 19:33:25    

Harkonnen a écrit :

sur des grosses boucles, ça procure un gain assez significatif

petites

Reply

Marsh Posté le 06-09-2005 à 10:59:40    

Taz+Harko> ça dépend du l'algo.
Mais même sur des grosses boucles (pas trop quand même), le gain est significatif.
Les meilleurs gains sont toujours obtenus sur des boucles occupant énormément la mémoire.
 
A l'inverse, trop dérouler une boucle (courte ou longue) peut la ralentir. Tout est une histoire de contexte, de CPU, dépendances...
 
L'idéal restant de faire plusieurs routines critiques et de choisir la plus rapide selon le contexte (test).


---------------
http://www.ikalizer.fr
Reply

Marsh Posté le 06-09-2005 à 10:59:40   

Reply

Marsh Posté le 06-09-2005 à 11:51:28    

non ça dépend pas. C'est juste une histoire de cache et de si le coût du saut est significatif par rapport à l'exécution du corps de la boucle.

Reply

Marsh Posté le 06-09-2005 à 14:24:24    

C'est un peu plus compliqué que ça, cher Taz, car les micro-processeurs avancés de notre génération sont très sophistiqués. Par exemple, ils utilisent une méthode appellé "prefectching" qui fait qu'un même saut peut être plus ou moins rapide selon que le CPU a deviné que le saut allait avoir lieu ou pas. Autre chose, le parallelisme. Puisque le microprocesseur possède un certain niveau de parallèlisme, il lui arrive d'exécuter plus ou moins rapidement une instruction en fonction de l'instruction qui la précède ou qui la suit. Donc, de nos jours, il devient quasiment impossible de faire des calculs théoriques justes du temps d'exécution. Il faut tester.


Message édité par olivthill le 06-09-2005 à 14:25:39
Reply

Marsh Posté le 06-09-2005 à 14:26:51    

Taz> Il n'y a pas que le coût du saut, il y a aussi les problèmes d'AGI et de parallélisation qui peuvent être améliorés voire résolus en déroulant partiellement les boucles.
 
Dans tous les cas, je ne déroule jamais totalement les boucles, c'est plus néfaste qu'autre chose, et cela salit le code-cache.
 
Souvent un déroulement x2 à x8 est suffisant.
 
Edit:
Taz> En fait tout dépend les algos. Je parle de ma propre expérience et toi de la tienne. Deux points de vue différents puisque l'on ne fait pas les mêmes choses.
 
Re-Edit:

Citation :

il devient quasiment impossible de faire des calculs théoriques justes du temps d'exécution. Il faut tester.


Oui il faut tester, mais il n'est pas impossible de faire des calculs théoriques. Il faut seulement avoir les bonnes docs et les connaissances.
 
Au fait, un processeur ne devine rien, il analyse suivant des algo complexes mais mathématiquement transposable. C'est bien plus pratique.


Message édité par christophe_d13 le 06-09-2005 à 14:31:44

---------------
http://www.ikalizer.fr
Reply

Sujets relatifs:

Leave a Replay

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