Microarchitectures pipelinés M1Info-ASE
Plan Notion de processeur à exécution pipeliné Le pipeline d’exécution du processeur DLX Les aléas d’exécution dans un pipeline Aléas de structurels et de contrôle Aléas de type flot de données M1Info-ASE
1. Limites de l’approche précédente Le chemin critique de l’UT limite la fmax du processeur. Il serait possible d’augmenter fmax en pipelinant l’UT par une coupe (qui ne serait pas légale …) On modifierait alors le comportement du processeur En effet, la boucle critique du chemin de donnée nous interdit d’utiliser le cut-set, et rend le retiming inefficace. M1Info-ASE
1. Notion de processeur pipeliné D’un point de vue « circuit » On va donc transformer l’architecture de manière à ce que l’ajout de registres de pipeline par coupe perturbe le moins possible le fonctionnement initial du processeur. D’un point de vue « fonctionnel » Pipeliner l’architecture revient à recouvrir l’exécution de plusieurs instructions consécutives Si le pipeline d’exécution contient n étage, une instruction dont l’exécution a commencé au cycle i se termine au cycle i+n. L’instr i+1 commence donc son exécution avant la fin de i ! M1Info-ASE
1. Exécution pipelinée Microarchitecture combinatoire Microarchitecture séquentielle Microarchitecture pipelinée Cycles machines 1 2 3 4 add r6,r5,r2 F+DC+EX+WB add r3,r1,r1 lw r8,10(r5) programme Cycles machines 1 2 3 4 5 6 7 add r6,r5,r2 F DC EX WB add r3,r1,r1 lw r8,10(r5) programme Cycles machines 1 2 3 4 5 6 7 8 add r6,r5,r2 F DC EX M WB add r3,r1,r1 lw r8,10(r5) programme M1Info-ASE
1. Notion de processeur pipeliné Dans ce chapitre, nous étudierons la MEO d’un processeur DLX disposant d’un pipeline à 5 étages. évoquerons également d’autres mises en œuvre de pipeline pour le DLX ou pour des processeurs similaires (MIPS) Nous ferons quelques simplifications Nous ne gèrerons pas les instruction de type jal rd,imm16 Nous ne gèrerons pas les instructions flottantes addf, multf M1Info-ASE
2. Le pipeline du DLX (vue structurelle) Étage FETCH Étage EXECUTE Étage MEM Étage WRITEBACK Étage DECODE M1Info-ASE
2. Les étages de pipeline du DLX Etage Instruction Fetch (F) Charge l’instruction suivant à partir de la mémoire de code, incrémente le registre PC Suppose un accès en 1 seul cycle à la mémoire d’instruction Etage Decode (D) Lit les opérandes de type registre, décode l’instruction dans IR, et calcule l’adresse destination d’un éventuel branchement Etage Execute (E) Réalise l’opération arithmétique, et résout les branchements Etage Memory (M) Effectue lecture/écriture en mémoire Suppose un accès en 1 cycle à la mémoire de données Etage Write back (W) Écrit le résultat de l’opération dans la file de registres M1Info-ASE
2. Le pipeline du DLX (vue structurelle) Étage FETCH Étage EXECUTE Étage MEM Étage WRITEBACK Étage DECODE I3 I2 I4 I0 I1 M1Info-ASE
2. Registres de pipeline du DLX Les étages du pipeline sont séparés par des registres On les désigne par convention à l’aide des noms d’étages de pipelines associés (exemple : IF/DC) Il servent à stocker les informations disponibles dans un étage et dont on a encore besoin dans les étages suivants. Exemple : le n° du registre Rd est obtenu à l’étage ID, mais on ne s’en sert qu’à l’étage WB, il faut donc passer cette information aux étages qui suivent. M1Info-ASE
2. Registres de pipeline du DLX Pas de registres nécessaires après l’étage de WriteBack Les résultats de l’étage WB sont par définition stockés dans la file de registres La file de registres sert de fait de registre de pipeline entre deux instructions. M1Info-ASE
2. Vue fonctionnelle du pipeline (synthèse) L’exécution des instructions est découpée en étages Chaque étage prend 1 cycle horloge pour s’exécuter Chaque étage dispose de ressources matérielles propres On peut donc exécuter plusieurs instructions en parallèle Chaque étage opère alors sur une instruction différente Il est alors possible d’exécuter une instruction à chaque cycle ! On va ainsi recouvrir l’exécution des instructions Si le pipeline d’exécution contient n étage, une instruction dont l’exécution a commencé au cycle i se termine au cycle i+n. L’instr i+1 commencera donc son exécution avant la fin de i ! Evidement, cela est plus compliqué qu’il n’y parait Du point de vue du jeu d’instruction, on s’attend à « voir » une machine qui ne commence l’inst. In+1 que lorsque In est terminée. M1Info-ASE
2. Le pipeline du DLX (vue fonctionnelle) Pour comprendre l’exécution d’un programme sur un processeur pipeliné, on utilise un tableau Cycles machines 1 2 3 4 5 6 7 8 add r6,r5,r2 F DC EX M WB add r3,r1,r1 lw r8,10(r5) add r6,r2,r6 addi r7,r7,r1 L’instruction n°2 commence son exécution au cycle 2 et la termine au cycle 8 programme Au cycle n°2, l’instruction n°0 est dans l’étage Fetch, l’instruction 1 est dans l’étage DeCode M1Info-ASE
3. Aléas de pipeline (hazards) Commencer l’inst In+1 avant la fin de In pose problème On ne respecte plus forcement la sémantique du programme original, car le résultat de In+1 peut dépendre de In ! Pour garantir le respect de cette sémantique, on sera parfois forcé de « geler» le pipeline. On appelle ce type de situation des aléas de pipeline Ces aléas réduisent les performances, car on n’exécute alors plus systématiquement une nouvelle instruction à chaque cycle On distingue trois grandes familles d’aléas de pipeline Aléas structurels : liés à des conflits d’accès à des ressources Aléas de contrôle : liés à la gestion du flot de contrôle Aléas de données : liés aux dépendances de données M1Info-ASE
4. Aléas structurels Définition Exemple : Quand deux opérations doivent être exécutées en même temps sur une même ressource matérielle. Exemple : Ces aléas peuvent être évités par l’ajout de ressources Dans notre exemple, on pourrait utiliser deux mémoires distinctes, une pour les données, une pour le programme. L’utilisation de mémoires de cache distinctes pour les instructions et les données résout également le problème Au cycle 4, il faut lire une donnée et charger une instruction en même temps, Si la mémoire qui contient le code et les données n’autorise qu’une lecture/cycle, on a un aléas structurel ! 1 2 3 4 5 6 lw r8,10(r6) F DC EX M WB add r3,r1,r6 add r6,r2,r6 M1Info-ASE
4. Aléas de contrôle : sauts Sur le DLX, on résout les sauts à l’étage ID. Le DLX ne détecte la présence d’une instruction de saut qu’une fois celle-ci chargée dans le registre IR, c-a-d à l’étage ID … Dans le cas de branchements conditionnels (bnez, beqz) le DLX est capable de déterminer à l’étage ID si il doit sauter ou non. Mais cela est trop tard ! Au moment ou le DLX décode l’instruction de saut In lue en PC, il a commencé à charger l’instruction qui suit (In+1 lue en PC+4). Si le saut doit être pris, cette instruction In+1 ne doit pas être exécutée, on va donc annuler son exécution. On crée donc un trou (bubble) dans le pipeline, et on perd par conséquent 1 cycle machine. Remarque : si le saut n’est pas pris => pas de pénalité M1Info-ASE
4. Aléas de contrôle : exemple Exemple : aléas de contrôle sur le DLX Ay cycle 4, on décode l’instruction de saut à l’adresse 200, mais on est déjà en train de charger l’instruction à l’adresse 108. On annule donc l’exécution de l’instruction à l’adresse 10B dès le cycle 5 (dans l’étage DC), mais on gaspille alors un cycle machine … 1 2 3 4 5 6 7 8 9 10 100: add r6,r5,r2 F DC EX M WB 104: add r3,r1,r6 108: j 200 10B: lw r8,10(r6) 200: lw r2,10(r1) 204: add r1,r2,r3 M1Info-ASE
Aléas de contrôle : exemple Saut conditionnels Dans le cas ou r2 vaut 0 au début de ce programme, le saut est pris, et on perd donc 1 cycle Dans le cas ou r2 ne vaut pas 0 au début de ce programme, le saut n’est pas pris, il n’y a pas besoin d’annuler l’exécution de l’instruction chargée au cycle 4. 1 2 3 4 5 6 7 8 9 10 108: bnez r2,200 F DC EX M WB 10B: lw r8,10(r6) 200: lw r2,10(r1) 204: add r1,r2,r3 Saut pris 1 2 3 4 5 6 7 8 9 10 108: bnez r2,200 F DC EX M WB 10B: lw r8,10(r6) 110: add r2,10(r1) 204: addi r1,r2,r3 Saut non pris M1Info-ASE
Aléas de contrôle : sauts Sur le DLX, un saut coûte en fait souvent 2 cycles ! 1 cycle pour exécuter l’instruction de saut proprement dite 1 cycle pour rectifier l’aléas de contrôle (si besoin) Et si la résolution du saut se fait plus tard ? Sur le MIPS, les sauts conditionnels sont plus complexes (deux registres opérandes, et un + grand nombre de conditions) Instruction : bxxx r1,r2,label Le MIPS utilise donc son UAL (étage EX) pour savoir si on doit prendre le saut ou non. La pénalité en cas de saut est alors plus importante ! Dans le cas du MIPS, on aura déjà envoyé deux instructions inutiles dans le pipeline Si l’étage d’exécution est lui-même pipeliné, la pénalité augmente encore d’autant ! M1Info-ASE
Aléas de contrôle On considère le DLX modifié dans lequel : Le pipeline est à 7 étages (3 étages pour l’exécution) La résolution des saut se fait à l’issu de l’étage d’exécution Dans ce cas, la pénalité est de 4 cycles ! On a du annuler 4 instr. envoyées par erreur dans le pipeline 1 2 3 4 5 6 7 8 9 10 11 12 13 14 100: add r6,r5,r2 F DC EX1 EX2 EX3 M WB 104: add r3,r1,r6 108: bnez r1,200 10B: lw r8,4(r6) 110: lw r1,16(r6) 114: sw 8(r6),r2 118: lw r4,24(r3) 200: lw r2,10(r1) 204: add r1,r2,r3 Ce n’est qu’à la fin du cycle 7 que l’on sait si on doit sauter ! M1Info-ASE
4. Aléas de contrôle : solutions Utilisation de mécanismes de prédiction de saut Mécanisme matériel qui essaie de prédire dès l’étage DC, si le branchement sera pris ou non. On se base sur l’historique d’exécution du programme Limite l’impact des pénalités si la prédiction est correcte Ne permet pas d’éliminer complètement la pénalité de saut Mécanisme très efficace pour les boucles for(), while() M1Info-ASE
4. Aléas de contrôle : solutions Utilisation d’un prédicteur de branchements Taux de succès du prédicteur = 85% Pénalité dans le cas d’une erreur de prédiction = 3 cycles Le profileur indique que 10% des instructions sont des branchements conditionnels Amélioration des performances = (cycles avant amélioration) / (cycles après amélioration) = 3 / [.15(3) + .85(1)] = 2.3 Facteur d’accélération (speedup) = 1 / (.90 + .10/2.3) = 1.06 Amélioration des performances de 6% … M1Info-ASE
4. Aléas de contrôle : solutions Utiliser un saut retardé (Delay Slot) Le saut est réalisé avec un « retard » de n instructions, en choisissant n pour qu’il corresponde à la pénalité de saut Les n instructions qui suivent l’instruction de saut sont ainsi exécutées que le saut soit pris ou non. On a alors plus besoin de les annuler C’est le principe utilisé dans les processeurs MIPS La gestion est remontée vers le programmeur Celui-ci doit essayer de « placer » des instructions utiles après le saut, ce qui n’est pas toujours simple … M1Info-ASE
4. Aléas de contrôle On reprend l’exemple précédent : Le pipeline est à 7 étages (3 étages pour l’exécution) On utilise des sauts retardés de 4 instructions Si on a réussi à placer des instructions utiles après le saut, la pénalité de saut est masquée. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 100: add r6,r5,r2 F DC EX1 EX2 EX3 M WB 104: add r3,r1,r6 108: Bnez r1, 200 10B: lw r8,4(r6) 110: lw r1,16(r6) 114: sw 8(r6),r2 118: lw r4,24(r3) 200: lw r2,10(r1) 204: add r1,r2,r3 Le saut n’est pris en compte que 4 instructions plus tard, en 118 M1Info-ASE
5. Aléas de données (1/2) Liés aux dépendances de données du programme Liés au flot de données des opérations effectuées par le programme. Ces dépendances sont organisées en trois catégories Dépendances de type RAW (Read After Write) Dépendances de type WAR (Write After Read) Dépendances de type WAW (Write After Write) M1Info-ASE
5. Dépendance RAW Dépendance Read after Write : Dans le cas du DLX Le résultat d’une instruction I est utilisé comme opérande par une instruction suivante I’. Dans ce cas de figure, I’ ne peut commencer avant la fin de I Dans le cas du DLX Le résultat d’une opération In n’est stocké dans la file de registres qu’à l’issue de l’étage WB. Ce résultat ne peut donc être utilisé par une instruction Im que lorsque In a atteint l’étage WB. Le problème apparaît des qu’un registre est utilisé comme opérande moins de deux instructions après avoir été modifié. M1Info-ASE
5. Aléas de données : dépendances RAW Exemple sur le DLX: Le registre r6 est modifié par l’instruction I100, et est utilisé comme opérande par l’instruction I104 Le registre r5 est modifié par l’instruction I108, et est utilisé comme opérande par les instructions I110 et I112 La pénalité varie entre 1 et 2 cycles ! 1 cycle de pénalité entre I108 et I110 2 cycles de pénalité entre I100 et I104 1 2 3 4 5 6 7 8 9 10 11 12 100: add r6,r5,r2 F DC EX M WB 104: add r3,r1,r6 108: add r5,r1,r2 10B: add r7,r2,r2 110: lw r1,16(r5) X 114: lw r2,4(r5) M1Info-ASE
5. Aléas de données et forwarding Pour résoudre ce type d’aléas, on utilise le forwarding On ajoute un chemin qui relie directement la sortie de l’étage d’exécution (EX) à son entrée ! Il est alors possible d’utiliser le résultat produit lors de l’étage EX au cycle n directement au cycle n+1 M1Info-ASE
5. Aléas de données et forwarding Le forwarding nécessite du matériel pour: Détecter les situation où on a effectivement besoin de forwarder un même registre R utilisé en opérande destination au cycle n et en opérande source au cycle n+1. Court-circuiter les opérandes en entrée de l’UAL Fils + 2 multiplexeurs supplémentaires Remarques Le forward ne permet pas de résoudre tous les aléas : lorsque l’étage d’exécution est pipeliné, on est bloqué encore une fois … Les multiplexeurs peuvent avoir un impact sur le chemin critique de l’architecture. M1Info-ASE
5. Aléas de données : limites du fowarding On considère le DLX modifié dans lequel : Le pipeline est à 7 étages (3 étages pour l’exécution) On dispose d’un mécanisme de forwarding. Dans ce cas, la pénalité est quand même de 2 cycles ! On a du attendre 2 tops avant que le résultat le la 1ère instruction (obtenu en EX3) soit utilisable à l’étage EX1 de la 2nd instruction fowarding 1 2 3 4 5 6 7 8 9 10 11 12 100: add r6,r5,r2 F DC EX1 EX2 EX3 M WB 104: add r3,r1,r6 108: j 200 10B: lw r8,4(r6) 110: lw r1,16(r6) M1Info-ASE
5. Aléas d’accès mémoire On peut avoir des aléas RAW à cause d’accès mémoire Utilisation d’un registre comme opérande juste après son chargement à partir de la mémoire. On utilise donc également une techniques de forwarding, Attention : puisque le résultat provient de la mémoire, il faut forwarder la sortie de l’étage M, et non pas celle de l’étage EX. Remarques : En cas de défaut dans le cache de donnée, (ou d’accès mémoire nécessitant plus d’un cycle pour se réaliser) on aura également un gel du pipeline. L’écriture mémoire ne pose pas ce genre de problèmes, car on peut la retarder Il faut quand même s’assurer que la dernière instruction d’écriture a bien eu lieu avant de lancer la prochaine lecture. M1Info-ASE
5. Aléas de données : limites du fowarding Aléas mémoire sans forwarding. Il faut attendre que la donnée lue en I100 soit écrite dans la file de registre avant de l’utiliser en opérande en I104. On a deux cycles de pénalité ! Aléas mémoire avec forwarding. On peut utiliser la lue en mémoire en I100 directement en entrée de l’étage d’exécution. On aura quand même 1 cycle de pénalité … 1 2 3 4 5 6 7 8 9 10 100: lw r8,4(r6) F DC EX M WB 104: add r3,r1,r8 1 2 3 4 5 6 7 8 9 10 100: lw r8,4(r6) F DC EX M WB 104: add r3,r1,r8 M1Info-ASE
Exercice 3 Représenter le fonctionnement du pipeline pour le code assembleur obtenu pour l’exercice 1. .data x: .space 4*100 y: .space 4*100 res: .float 0 .text lf f4,res(r0) forloop: lf f1,x(r2) lf f2,y(r2) multf f3,f1,f2 addf f4,f3,f4 addi r2,r2,4 subi r1,r2,400 bnez r1,forloop endfor: sf f4,res(r0) Pas d’aléas d’accès mémoire, (les données sont toujours dans le cache) Pipeline à 5 étage pour les opérations entières (F,DC,EX,M,WB). Quatre étages (F,DC,EX1,…EX4,M,WB). pour l’addition et la multiplication flottante Mécanisme de forward. sauts résolus à l’étage DC, pas de prédiction de branchement ni de saut retardé. M1Info-ASE
Exercice 3 Corrigé Performances : 15 cycles/itération M1Info-ASE 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 addi r2,r0,0 F D EX M WB lf f4,RES(r0) loop: lf f1,X(r2) lf f2,Y(r2) multf f3,f2,f1 EX1 EX2 EX3 EX4 addf f4,f3,f4 addi r2,r2,4 subi r1,r2,400 bnez r1,loop sf f4,res(r0) bnez r1,forloop M1Info-ASE
Exercice 3 : corrigé Mise en œuvre « optimisée » Performances : 11 cycles/itération 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 addi r2,r0,0 F D EX M WB lf f4,RES(r0) forloop: lf f1,X(r2) lf f2,Y(r2) addi r2,r2,4 multf f3,f2,f1 EX1 EX2 EX3 EX4 subi r1,r2,400 addf f4,f3,f4 bnez r1,forloop sf f4,res(r0) M1Info-ASE
Exercice 3 : déroulage de boucle Déroulage par un facteur 2 Résultat : 7 cycles/itération 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 addi r2,r0,0 F D EX M WB lf f8,RES(r0) forloop: lf f1,X+400(r2) lf f2,Y+400(r2) lf f3,X+404(r2) multf f5,f2,f1 EX1 EX2 EX3 EX4 lf f4,Y+404(r2) addi r2,r2,8 multf f6,f3,f4 addf f7,f5,f8 addf f8,f7,f6 bnez r2,forloop sf f8,res(r0) Valeur de f8 produite à l’itération précédente Aléa RAW Aléa de contrôle M1Info-ASE
Exercice 3 : déroulage de boucle Déroulage par un facteur 4 Résultat : ~5,5 cycles/itération addi r2,r0,0 F D EX M WB lf f8,RES(r0) loop: lf f1,X+400(r2) lf f2,Y+400(r2) lf f3,X+404(r2) multf f9,f2,f1 EX1 EX2 EX3 EX4 lf f4,X+404(r2) lf f5,X+408(r2) multf f10,f4,f3 lf f6,Y+408(r2) lf f7,X+412(r2) multf f11,f6,f5 lf f8,X+412(r2) addf f15,f9,f15 multf f12,f8,f7 addi r2,r2,8 addf f13,f10,f11 addf f15,f15,f12 addf f15,f13,f15 bnez r2,forloop lf f14,X(R2) Aléas structurel au niveau de l’étage d’accès mémoire ! On a une pénalitée provoquée par un aléas inter-itération 21+1 cycles M1Info-ASE
Exercice 4 Représenter le fonctionnement du pipeline pour le code assembleur de l’exercice 2. float z1,z,u1,u,y1,y,dz; while (z<a) { z1 = z + dz; u1 = u – (3*z*u*dz) – (3*y*dz); y1 = y + (u*dz); z = z1; u = u1; y = y1; } M1Info-ASE
Pipeline à longueur variable Efficacité pour les calculs flottants Pour obtenir des performances élevées en calcul flottant, il est nécessaire de pipeliner l’étage d’exécution (entre 3 et 6 étages) Ces étages supplémentaires vont engendrer des pénalités plus importante alors même que les calculs flottants ne représentent qu’une partie des traitements. On utilise donc un pipeline de longueur variable 1 étage d’exécution pour les opérations entières De 3 à 5 étages d’exécution pour les opérations flottantes Mais cela engendre de nouveaux problèmes Aléas de type WAW : Write After Write M1Info-ASE
Aléas Write After Write On suppose la version modifiée du DLX ci-dessous: 3 étages d’exécution pour les additions flottantes 5 étages d’exécution pour les multiplication flottantes Quand on détecte un aléas WAW, on gèle le pipeline On garantit que l’écriture se fait dans le bon ordre. 1 2 3 4 5 6 7 8 9 10 11 100: multf f6,f5,f2 F DC EX1 EX2 EX3 EX4 EX5 M WB 104: addf f6,f3,f2 Le résultat de I104 est écrasé par le résultat de I100 ! 1 2 3 4 5 6 7 8 9 10 11 100: multf f6,f5,f2 F DC EX1 EX2 EX3 EX4 EX5 M WB 104: addf f6,f3,f2 X M1Info-ASE
Aléas structurel à l’étage MEM Aléas structurels On suppose la version modifiée du DLX ci-dessous: 3 étages d’exécution pour les additions flottantes Quand on détecte cet type d’aléas, on gèle le pipeline On garantit qu’il n’y a pas 2 instructions en même temps dans l’étage MEM. Aléas structurel à l’étage MEM 1 2 3 4 5 6 7 8 9 10 100: addf f6,f5,f2 F DC EX1 EX2 EX3 M WB 104: Lf f4,(f4) 108: lf f2,(f3) 1 2 3 4 5 6 7 8 9 10 100: addf f6,f5,f2 F DC EX1 EX2 EX3 M WB 104: Lf f4,(f4) 108: lf f2,(f3) X M1Info-ASE
Conclusion Tous les processeurs modernes sont pipelinés Exemple : le P4 dispose d’une vingtaine d’étages de pipeline !! Technique clé dans les années 80 pour améliorer les performances, mais a atteint rapidement ses limites. Comment peut-on encore améliorer les performances ? On utilise non plus un mais plusieurs pipelines en parallèle ! C’est une technique qui a été développée dans les années 90 Approches super-scalaire pour les stations de travail Approche VLIW pour l’embarqué (c’est la suite du cours !) M1Info-ASE
Poubelle M1Info-ASE
Exercice 3 lf f4,res(r0) lf f4,res(r0) forloop: forloop: lf f1,x+400(r2) lf f2,y+400(r2) multf f3,f1,f2 addf f4,f3,f4 lf f1,x+404(r2) lf f2,y+404(r2) addi r2,r2,8 bnez r2,forloop endfor: sf f4,res(r0) lf f4,res(r0) forloop: lf f1,x+400(r2) lf f2,y+400(r2) multf f3,f1,f2 addf f4,f3,f4 addi r2,r2,4 bnez r2,forloop endfor: sf f4,res(r0) M1Info-ASE
Exercice 3 forloop: lf f1,x+400(r2) lf f2,y+400(r2) multf f3,f1,f2 addf f4,f3,f4 lf f1,x+404(r2) lf f2,y+404(r2) addi r2,r2,16 bnez r2,forloop lf f4,res(r0) forloop: lf f1,x+400(r2) lf f2,y+400(r2) multf f3,f1,f2 addf f4,f3,f4 lf f1,x+404(r2) lf f2,y+404(r2) addi r2,r2,8 bnez r2,forloop endfor: sf f4,res(r0) M1Info-ASE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 addi r2,r0,0 F D EX M WB lf f8,RES(r0) forloop: lf f1,X+400(r2) lf f2,Y+400(r2) lf f3,X+404(r2) lf f4,X+404(r2) lf f5,X+408(r2) lf f6,Y+408(r2) lf f7,X+412(r2) lf f8,X+412(r2) multf f9,f2,f1 EX1 EX2 EX3 EX4 multf f10,f4,f3 multf f11,f6,f5 multf f12,f8,f7 addf f13,f9,f10 addf f14,f11,f12 addf f13,f13,f8 addf f8,f13,f14 addi r2,r2,8 bnez r2,forloop M1Info-ASE
forloop: lf f1,x+400(r2) lf f2,y+400(r2) multf f3,f1,f2 addf f4,f3,f4 lf f1,x+404(r2) lf f2,y+404(r2) addi r2,r2,16 bnez r2,forloop forloop: lf f1,x+400(r2) lf f2,y+400(r2) lf f5,x+404(r2) multf f3,f1,f2 lf f6,y+404(r2) lf f9,x+400(r2) lf f10,y+400(r2) addf f4,f3,f4 lf f13,x+404(r2) lf f14,y+404(r2) addi r2,r2,16 multf f11,f9,f10 addf f12,f12,f11 bnez r2,forloop M1Info-ASE