Changes between Initial Version and Version 1 of TracRevision


Ignore:
Timestamp:
Oct 19, 2020, 1:30:40 PM (4 years ago)
Author:
meunier
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • TracRevision

    v1 v1  
     1
     2= M1 SESI – Architecture des Processeurs et Optimisation =
     3
     4= TD2 – Pipeline MIPS =
     5
     6Ce TD se focalise sur les points suivants :
     7* Le schéma d'exécution des instructions dans la réalisation pipeline du Mips
     8* La dépendance de données dans le pipeline
     9* Le problème des branchements dans le pipeline
     10* Évaluation du nombre cycles nécessaires pour l'exécution d'un code, CPI, CPI-utile
     11
     12
     13= Exercice 1 : =
     14
     15Montrer à l'aide d'un schéma détaillé l'exécution de l'instruction `SLLV rd, rt, rs` (Shift Left Logic Variable) dans le pipeline du Mips-32.
     16
     17
     18'''''Solution 1 :'''''
     19
     20Le schéma détaillé présente l'évolution de l'instruction à chaque étage du pipeline (représentation utilisée en cours). L'axe horizontal est l'axe du temps découpé en cycles d'horloge (chaque trait vertical représente un front montant d'horloge). On ne représente que les ressources matérielles (registres, signaux, parties combinatoires) qui interviennent dans l'exécution de l'instruction et qui présentent un intérêt pour la compréhension de l'exécution.
     21
     22[[Image(htdocs:/corrige/Seance3/S3_corrige_Q1.svg)]]
     23
     24'''Remarque importante''' : Sur une même ligne, on représente l'évolution d'un matériel donné au cours du temps. Ainsi, il faut réserver une ligne pour chaque registre représenté. Il ne faut pas faire figurer sur une même ligne deux registres différents.
     25
     26Chaque ressource matérielle appartient à un cycle du pipeline (le cycle dans lequel elle est modifiée). Elle porte un nom suffixé par une lettre qui indique le cycle du pipeline auquel elle appartient. Par exemple, le registre qui reçoit l'instruction lue depuis la mémoire s'appelle `I_RI` : les deux lettres du suffixe indiquent qu'il s'agit d'un registre (R) et qu'il appartient au cycle `IFC` (la dernière lettre I).
     27
     28= Exercice 2 : =
     29
     30Montrer à l’aide d’un schéma détaillé l’exécution de l’instruction `BLTZAL rs, label` (Branch if Less Than Zero And Link) dans le pipeline du Mips-32.
     31
     32
     33'''''Solution 2 :'''''
     34
     35Il s'agit d'une instruction de branchement conditionnel à un sous-programme. L'adresse de retour est sauvegardée dans le registre R31. Il faut noter que la sauvegarde s'effectue dans tous les cas (que le branchement réussisse ou non).
     36
     37[[Image(htdocs:/corrige/Seance3/S3_corrige_Q2.svg)]]
     38
     39L'adresse de retour est l'adresse de l'instruction de branchement + 8 (à cause du delayed slot qui s'exécute avant l'exécution de l'instruction cible du branchement).
     40
     41On utilise deux additionneurs pour accélérer le calcul de l'adresse. On calcule les deux adresses possibles et on choisit après en fonction du résultat de la condition de branchement. L'adresse de branchement est
     42
     43{{{
     44    @_de_l'instruction_de_branchement + 4 + Imd * 4
     45}}}
     46
     47Il faut remarquer que, dans ce calcul, le + 4 a déjà été effectué par l'instruction qui précède le branchement.
     48
     49
     50= Exercice 3 : =
     51
     52On considère une nouvelle instruction de branchement conditionnel : l'instruction `BEQPI` (Branch if equal and post increment).
     53{{{
     54    Beqpi    rs, rt, Label
     55}}}
     56
     57Il s'agit d'une instruction de format I. Cette instruction réalise l'opération suivante. Comme pour BEQ, le contenu de RS est comparé au contenu de RT. En cas d'égalité, on se branche à l'instruction portant l'étiquette Label, sinon le branchement échoue et on continue en séquence. De plus, une fois le test effectué, le contenu de RT est incrémenté.
     58
     59Le schéma d'exécution du pipeline du Mips convient-il à l'exécution de cette instruction ? Si oui, proposer un schéma détaillé montrant l'exécution de cette instruction. Si non, expliquer pourquoi.
     60
     61
     62'''''Solution 3 :'''''
     63
     64[[Image(htdocs:/corrige/Seance3/S3_corrige_Q3.svg)]]
     65
     66Cette instruction peut être exécutée dans le pipeline du Mips puisque l'incrémentation de RT s'effectue après l'évaluation de la condition de branchement. Cette incrémentation peut être prise en charge par le cycle EXE. Puis, la mise à jour de RT s'effectue naturellement dans le cycle `WBK` en sélectionnant RT comme registre destinataire.
     67
     68
     69
     70= Exercice 4 : =
     71
     72On considère une nouvelle instruction de branchement conditionnel : l'instruction BEQPD (Branch if equal and pre-decrement).
     73{{{
     74    Beqpd    rs, rt, Label
     75}}}
     76
     77Il s'agit d'une instruction de format I. Cette instruction réalise l'opération suivante. Comme pour `BEQ`, le contenu de RS est comparé au contenu de RT. En cas d'égalité, on se branche à l'instruction portant l'étiquette Label, sinon le branchement échoue et on continue en séquence. En plus, avant d'effectuer le test, le contenu de RT est decrémenté.
     78
     79Le schéma d'exécution du pipeline du Mips convient-il à l'exécution de cette instruction ? Si oui, proposer un schéma détaillé montrant l'exécution de cette instruction. Si non, expliquer pourquoi.
     80
     81
     82'''''Solution 4 :'''''
     83
     84Cette instruction ne peut pas être exécutée dans le pipeline du Mips. En effet, avant d'évaluer la condition de branchement, il faut décrémenter RT. Cette action doit donc s'effectuer dans le cycle DEC puisque c'est dans ce cycle que s'effectue le calcul de l'adresse cible du branchement. Or, il est clair que l'ensemble de ces opérations (lecture des opérandes, décrémentation de RT puis, évaluation de la condition de branchement) nécessite un temps bien supérieur au temps de cycle si l'on considère comme référence pour la période d'horloge, le temps nécessaire à l'exécution de l'étage `EXE` (un calcul - typiquement une addition - et un multiplexeur pour sélectionner le résultat parmi tous les résultats calculés par les différents opérateurs). Ainsi, l'exécution de cette instruction dans le pipeline du MIPS aboutirait à un pipeline fortement déséquilibré ce qui est contraire aux règles de conception des pipelines.
     85
     86
     87
     88= Exercice 5 : =
     89
     90Montrer à l’aide d’un schéma détaillé l’exécution de la suite d’instructions suivante dans le pipeline du Mips-32.
     91{{{
     92    Add    r3 , r2 , r1
     93    Add    r3 , r3 , r1
     94}}}
     95
     96Quelle est la condition du déclenchement des bypass ?
     97
     98
     99'''''Solution 5 :'''''
     100
     101[[Image(htdocs:/corrige/Seance3/S3_corrige_Q5.svg)]]
     102
     103On remarque une dépendance de données entre ces deux instructions (sur RS). Cette dépendance est résolue grâce à un bypass entre la sortie de l'étage EXE de la première instruction et le début de l'étage `EXE` de la seconde.
     104Le multiplexeur qui se trouve avant l'additionneur est le bypass. Il se déclenche lorsque le numéro du registre RS de l'instruction courante (I_RD) est identique au numéro du registre RD de l'instruction précédente (I_RE).
     105
     106
     107
     108= Exercice 6 : =
     109
     110Montrer à l’aide d’un schéma détaillé l’exécution de la suite d’instructions suivante dans le pipeline du Mips-32.
     111{{{
     112    Add    r0 , r2 , r1
     113    Add    r3 , r0 , r1
     114}}}
     115Donner l'expression exacte de la condition du déclenchement des bypass ?
     116
     117
     118'''''Solution 6 :'''''
     119
     120A première vue on pourrait penser qu'il y a une dépendance de données entre ces deux instructions. Cependant, ce n'est pas le cas car la première instruction écrit dans le registre R0 (en fait, cette instruction ne fait rien). Autrement dit, il ne faut pas activer le bypass. Le schéma simplifié est le suivant.
     121
     122[[Image(htdocs:/corrige/Seance3/S3_corrige_Q6_a.svg)]]
     123
     124Le schéma détaillé correspond à l'exécution de 2 instructions d'addition.
     125
     126[[Image(htdocs:/corrige/Seance3/S3_corrige_Q6_b.svg)]]
     127
     128On peut donc dire que le bypass se déclenche si le numéro du registre RS de l'instruction courante (I_RD) est identique au numéro du registre RD de l'instruction précédente (I_RE) et qu'il ne s'agit pas du numéro 0. Il faut ajouter à cette condition : il faut que l'instruction précédente écrive dans le registre RD et que l'instruction courante ait besoin du registre RS.
     129
     130
     131
     132= Exercice 7 : =
     133
     134Montrer à l’aide d’un schéma détaillé l’exécution de la suite d’instructions suivante dans le pipeline du Mips-32.
     135{{{
     136    Lw    r3 , 0 (r2)
     137    Add   r3 , r3 , r1
     138}}}
     139
     140
     141'''''Solution 7 :'''''
     142
     143Il y a une dépendance de données entre ces deux instructions qui provoque un cycle de gel (stall).
     144
     145[[Image(htdocs:/corrige/Seance3/S3_corrige_Q7.svg)]]
     146
     147
     148
     149= Exercice 8 : =
     150
     151Analyser l’exécution de la suite d’instructions suivante dans le processeur Mips-32 à l’aide d’un schéma simplifié.
     152{{{
     153#!asm
     154    Addiu  r2 , r0 , 4
     155    Lui    r3 , 0x000c
     156    Add    r2 , r2 , r2
     157    Ori    r3 , r3 , 0x4568
     158    Lw     r2 , 0(r3)
     159    Lbu    r2 , 0(r2)
     160    Ori    r2 , r2 , 0x0001
     161    Bltzal r2 , suite
     162    Addu   r0 , r0 , r0
     163suite:
     164    Jr     r31
     165    Addu   r31, r31, -8
     166}}}
     167
     168
     169'''''Solution 8 :'''''
     170
     171Le schéma suivant montre les dépendances de données dans ce code.
     172
     173[[Image(htdocs:/corrige/Seance3/S3_corrige_Q8_a.svg)]]
     174
     175
     176[[Image(htdocs:/corrige/Seance3/S3_corrige_Q8_b.svg)]]
     177
     178
     179
     180   
     181= Exercice 9 : =
     182
     183La réalisation du processeur Mips-32 nécessite la mise en œuvre de 8 bypass (raccourcis). Pour chacun de ces bypass, proposer un exemple de suite d'instructions qui illustre la nécessité de ce bypass.
     184
     185
     186'''''Solution 9 :'''''
     187
     188Il existe deux bypass (un sur RS et un sur RT) entre la sortie de l'étage `EXE` et le début de l'étage `EXE`. Ces bypass résolvent les dépendances de données d'ordre 1 (entre une instruction et l'instruction qui la précède).
     189
     190[[Image(htdocs:/corrige/Seance3/S3_corrige_Q9_a.svg)]]
     191
     192Exemple (bypass sur RS) :
     193{{{
     194    Add    r3 , r2 , r1
     195    Add    r3 , r3 , r4
     196}}}
     197
     198Exemple (bypass sur RT) :
     199{{{
     200    Add    r3 , r2 , r1
     201    Add    r3 , r4 , r3
     202}}}
     203
     204Il existe deux bypass (un sur RS et un sur RT) entre la sortie de l'étage `EXE` et le début de l'étage `DEC`. Ces bypass résolvent les dépendances de données d'ordre 2 (entre une instruction et la deuxième instruction qui la précède). Ces bypass sont nécessaires lorsque l'opérande (RS ou RT) est consommé dans le cycle `DEC`.
     205
     206[[Image(htdocs:/corrige/Seance3/S3_corrige_Q9_b.svg)]]
     207
     208Exemple (bypass sur RS) :
     209{{{
     210    Add    r3 , r2 , r1
     211    ... (une instruction quelconque)
     212    Beq    r3 , r4 , Suite
     213}}}
     214
     215Exemple (bypass sur RT) :
     216{{{
     217    Add    r3 , r2 , r1
     218    ... (une instruction quelconque)
     219    Beq    r4 , r3 , Suite
     220}}}
     221
     222Il existe deux bypass (un sur RS et un sur RT) entre la sortie de l'étage `MEM` et le début de l'étage `EXE`. Ces bypass résolvent les dépendances de données d'ordre 2 (entre une instruction et la deuxième instruction qui la précède). Ces bypass sont nécessaires lorsque l'opérande (RS ou RT) est produit par le cycle `MEM`.
     223
     224[[Image(htdocs:/corrige/Seance3/S3_corrige_Q9_c.svg)]]
     225
     226Exemple (bypass sur RS) :
     227{{{
     228    Lw    r3 , 0 (r2)
     229    ... (une instruction quelconque)
     230    Add    r5 , r3 , r4
     231}}}
     232
     233Exemple (bypass sur RT) :
     234{{{
     235    Lw    r3 , 0 (r2)
     236    ... (une instruction quelconque)
     237    Add    r5 , r4 , r3
     238}}}
     239
     240Il existe deux bypass (un sur RS et un sur RT) entre la sortie de l'étage `MEM` et le début de l'étage `DEC`. Ces bypass résolvent les dépendances de données d'ordre 3 (entre une instruction et la troisième instruction qui la précède).
     241
     242[[Image(htdocs:/corrige/Seance3/S3_corrige_Q9_d.svg)]]
     243
     244Exemple (bypass sur RS) :
     245{{{
     246    Add    r3 , r2 , r1
     247    ... (une instruction quelconque)
     248    ... (une instruction quelconque)
     249    Add    r5 , r3 , r4
     250}}}
     251
     252Exemple (bypass sur RT) :
     253{{{
     254    Add    r3 , r2 , r1
     255    ... (une instruction quelconque)
     256    ... (une instruction quelconque)
     257    Add    r5 , r4 , r3
     258}}}
     259
     260
     261
     262= Exercice 10 : =
     263
     264La fonction strlen calcule le nombre de caractères :
     265{{{
     266#!c
     267unsigned int strlen (char * str) {
     268   unsigned int i = 0;
     269   while (str [i] != '\0') {
     270      i++;
     271   }
     272   return (i);
     273}
     274}}}
     275
     276Différents codes assembleur peuvent être produits pour cette fonction pour un processeur non-pipeline :
     277
     2781ère version :
     279{{{
     280#!asm
     281_strlen:
     282    Addiu    r29, r29, -1*4
     283    Addu     r2, r0 , r0    ; initialisation
     284_strlen_loop:
     285    Lb       r9 , 0(r4)     ; lire 1 caractere
     286    Beq      r9 , r0 , _strlen_end_loop    ; fin de chaine ?
     287    Addiu    r4 , r4 , 1    ; caractere suivant
     288    Addiu    r2 , r2 , 1    ; caractere suivant
     289    J        _strlen_loop   ; boucle
     290
     291_strlen_end_loop:
     292    Addiu    r29, r29, 1*4
     293    Jr       r31
     294}}}
     295
     2962ème version :
     297{{{
     298#!asm
     299_strlen:
     300    Addiu    r29, r29, -1*4
     301    Addiu    r2, r0 , -1    ; initialisation
     302_strlen_loop:
     303    Lb       r9 , 0(r4)     ; lire 1 caractere
     304    Addiu    r4 , r4 , 1    ; caractere suivant
     305    Addiu    r2 , r2 , 1    ; caractere suivant
     306    Bne      r9 , r0 , _strlen_loop    ; fin de chaine ?
     307
     308    Addiu    r29, r29, 1*4
     309    Jr       r31
     310}}}
     311
     3123ème version :
     313{{{
     314#!asm
     315_strlen:
     316    Addiu    r29, r29, -1*4
     317    Addiu    r8, r4 ,  1    ; sauvegarde adresse debut
     318_strlen_loop:
     319    Lb       r9 , 0(r4)     ; lire 1 caractere (octet)
     320    Addiu    r4 , r4 , 1    ; caractere suivant
     321    Bne      r9 , r0 , _strlen_loop    ; fin de chaine ?
     322    Subu     r2 , r4 , r8    ; calculer nbr de carac
     323
     324    Addiu    r29, r29, 1*4
     325    Jr       r31
     326}}}
     327
     328Pour chacune des trois versions, transformer le code de telle façon qu'il puisse être exécuté sur le processeur Mips pipeline à 5 étages.
     329
     330
     331'''''Solution 10 :'''''
     332
     333Dans le processeur Mips, l'instruction qui suit un branchement est exécutée dans tous les cas. Pour tenir compte de cette particularité, sans perturber le code généré par le compilateur, il suffit d'ajouter une instruction NOP après chaque branchement.
     334
     3351ère version :
     336{{{
     337#!asm
     338_strlen:
     339    Addiu    r29, r29, -1*4
     340    Addu     r2, r0 , r0    ; initialisation
     341_strlen_loop:
     342    Lb       r9 , 0(r4)     ; lire 1 caractere
     343    Beq      r9 , r0 , _strlen_end_loop    ; fin de chaine ?
     344    Nop
     345    Addiu    r4 , r4 , 1    ; caractere suivant
     346    Addiu    r2 , r2 , 1    ; caractere suivant
     347    J        _strlen_loop   ; boucle
     348    Nop
     349
     350    Addiu    r29, r29, 1*4
     351    Jr       r31
     352    Nop
     353}}}
     354
     3552ème version :
     356{{{
     357#!asm
     358_strlen:
     359    Addiu    r29, r29, -1*4
     360    Addiu    r2, r0 , -1    ; initialisation
     361_strlen_loop:
     362    Lb       r9 , 0(r4)     ; lire 1 caractere
     363    Addiu    r4 , r4 , 1    ; caractere suivant
     364    Addiu    r2 , r2 , 1    ; caractere suivant
     365    Bne      r9 , r0 , _strlen_loop    ; fin de chaine ?
     366    Nop
     367
     368    Addiu    r29, r29, 1*4
     369    Jr       r31
     370    Nop
     371}}}
     372
     3733ème version :
     374{{{
     375#!asm
     376_strlen:
     377    Addiu    r29, r29, -1*4
     378    Addiu    r8, r4 ,  1    ; sauvegarde adresse debut
     379_strlen_loop:
     380    Lb       r9 , 0(r4)     ; lire 1 caractere (octet)
     381    Addiu    r4 , r4 , 1    ; caractere suivant
     382    Bne      r9 , r0 , _strlen_loop    ; fin de chaine ?
     383    Nop
     384    Subu     r2 , r4 , r8    ; calculer nbr de carac
     385
     386    Addiu    r29, r29, 1*4
     387    Jr       r31
     388    Nop
     389}}}
     390
     391
     392Analyser l'exécution de la boucle sur le processeur Mips à l'aide d'un schéma simplifié.
     393
     394
     395'''''Solution 10 :'''''
     396
     3971ère version :
     398
     399[[Image(htdocs:/corrige/Seance3/S3_corrige_Q10_1_a.svg)]]
     400
     401[[Image(htdocs:/corrige/Seance3/S3_corrige_Q10_1_b.svg)]]
     402
     4032ème version :
     404
     405[[Image(htdocs:/corrige/Seance3/S3_corrige_Q10_2_a.svg)]]
     406
     407[[Image(htdocs:/corrige/Seance3/S3_corrige_Q10_2_b.svg)]]
     408
     4093ème version :
     410
     411[[Image(htdocs:/corrige/Seance3/S3_corrige_Q10_3_a.svg)]]
     412
     413[[Image(htdocs:/corrige/Seance3/S3_corrige_Q10_3_b.svg)]]
     414
     415   
     416
     417Calculer le nombre de cycles nécessaires à l'exécution d'une itération de la boucle.
     418
     419
     420'''''Solution 10 :'''''
     421
     422 * 1ère version : 9 cycles par itération
     423 * 2ème version : 5 cycles par itération
     424 * 3ème version : 5 cycles par itération
     425
     426
     427
     428Calculer le CPI et le CPI-utile de la boucle.
     429
     430
     431'''''Solution 10 :'''''
     432
     433 * 1ère version : CPI = 9/7 cycles/inst  --  CPI-utile = 9/5 cycles/inst
     434 * 2ème version : CPI = 5/5 cycles/inst  --  CPI-utile = 5/4 cycles/inst
     435 * 3ème version : CPI = 5/4 cycles/inst  --  CPI-utile = 5/3 cycles/inst
     436
     437
     438
     439
     440= Exercice 11 :  =
     441
     442La fonction strupper transforme une chaîne de caractères en majuscules :
     443{{{
     444#!c
     445char * strupper (char * src) {
     446   int i = 0;
     447   while (src[i] != '\0') {
     448      if ((src[i] >= 'a') && (src[i] <= 'z')) {
     449         src[i] = src[i] - 'a' + 'A'
     450      }
     451      i++;
     452   }
     453   return src;
     454}
     455}}}
     456
     457La compilation de cette fonction pour un processeur non-pipeline a produit le code suivant:
     458{{{
     459#!asm
     460_strupper:
     461    Addiu    r29, r29, -1*4
     462
     463    Addu    r2 , r0 , r4     ; valeur de retour
     464    Addiu   r11, r0 , 'a'    ; pour la comparaison
     465    Addiu   r12, r0 , 'z'    ; pour la comparaison
     466
     467_strupper_loop:
     468    Lb      r8 , 0(r4)       ; lire src[i]
     469    Slt     r9 , r8 , r11    ; src[i] < 'a'
     470    Slt     r10, r12, r8     ; 'z'    < src[i]
     471    Or      r10, r10, r9     ; et des 2 conditions
     472    Bne     r10, r0 , _strupper_endif    ; si 1 des 2 cond vraie
     473    Addiu   r8 , r8 , 'A'-'a'; transformer en majuscule
     474    Sb      r8 , 0(r4)
     475
     476_strupper_endif:
     477    Addiu   r4 , r4 , 1      ; caractère suivant
     478    Bne     r8 , r0 , _strupper_loop
     479
     480    Addiu   r29, r29, 1*4
     481    Jr      r31
     482}}}
     483
     484Transformer ce code de telle façon qu'il puisse être exécuté sur le processeur Mips pipeline à 5 étages.
     485
     486
     487'''''Solution 11 :'''''
     488
     489Dans le processeur Mips, l'instruction qui suit un branchement est exécutée dans tous les cas. Pour tenir compte de cette particularité, sans perturber le code généré par le compilateur, il suffit d'ajouter une instruction NOP après chaque branchement.
     490
     491{{{
     492#!asm
     493__strupper:
     494    Addiu    r29, r29, -1*4
     495
     496    Addu    r2 , r0 , r4     ; valeur de retour
     497    Addiu   r11, r0 , 'a'    ; pour la comparaison
     498    Addiu   r12, r0 , 'z'    ; pour la comparaison
     499
     500_strupper_loop:
     501    Lb      r8 , 0(r4)       ; lire src[i]
     502    Slt     r9 , r8 , r11    ; src[i] < 'a'
     503    Slt     r10, r12, r8     ; 'z'    < src[i]
     504    Or      r10, r10, r9     ; et des 2 conditions
     505    Bne     r10, r0 , _strupper_endif    ; si 1 des 2 cond vraie
     506    Nop
     507    Addiu   r8 , r8 , 'A'-'a'; transformer en majuscule
     508    Sb      r8 , 0(r4)
     509
     510_strupper_endif:
     511    Addiu   r4 , r4 , 1      ; caractère suivant
     512    Bne     r8 , r0 , _strupper_loop
     513    Nop
     514
     515    Addiu   r29, r29, 1*4
     516    Jr      r31
     517    Nop
     518}}}
     519
     520
     521Analyser l'exécution de la boucle sur le processeur Mips à l'aide d'un schéma simplifié dans le cas où le `if` (du code source) réussit, puis dans le cas où le `if` échoue.
     522
     523
     524'''''Solution 11 :'''''
     525
     526Attention, il y a une dépendance entre le dernier `Addiu` et le `Lb` de l'itération suivante.
     527
     528[[Image(htdocs:/corrige/Seance3/S3_corrige_Q11_a.svg)]]
     529
     530Cas où le `if` réussit :
     531
     532[[Image(htdocs:/corrige/Seance3/S3_corrige_Q11_b.svg)]]
     533
     534Cas où le `if` échoue :
     535
     536[[Image(htdocs:/corrige/Seance3/S3_corrige_Q11_c.svg)]]
     537
     538
     539Calculer le nombre de cycles nécessaires à l'exécution d'une itération de la boucle dans le cas ou le `if` réussit.
     540
     541
     542'''''Solution 11 :'''''
     543
     544Il faut 13 cycles pour une itération si le `if` réussit
     545
     546
     547Calculer le nombre de cycles nécessaires à l'exécution d'une itération de la boucle dans le cas ou le `if` échoue.
     548
     549
     550'''''Solution 11 :'''''
     551
     552Il faut 11 cycles pour une itération si le `if` échoue.
     553
     554
     555Sachant que 30% des caractères sont minuscules calculer le CPI et le CPI-utile de la boucle.
     556
     557
     558'''''Solution 11 :'''''
     559
     560CPI = 1.208 cycle/instruction
     561
     562CPI_utile = 1.526 cycle/instruction utile
     563
     564
     565   
     566= Exercice 12 : =
     567
     568La fonction suivante calcule le PGCD de deux nombres positifs non nuls :
     569{{{
     570#!c
     571unsigned int pgcd (unsigned int a, unsigned int b) {
     572   while (a != b) {
     573      if (a < b) {
     574          b = b - a;
     575      }
     576      else {
     577          a = a - b;
     578      }
     579   }
     580   return a;
     581}
     582}}}
     583
     584La compilation de cette fonction pour un processeur non-pipeline a produit le code suivant:
     585{{{
     586#!asm
     587_pgcd:
     588    Beq     r4 , r5 , _pgcd_end
     589
     590_pgcd_loop:
     591    Sltu    r8 , r4 , r5    ; a < b
     592    Beq     r8 , r0 , _pgcd_else
     593    Subu    r5 , r5 , r4
     594    J       _pgcd_endif
     595
     596_pgcd_else:
     597    Subu    r4 , r4 , r5
     598_pgcd_endif:
     599    Bne     r4 , r5 , _pgcd_loop
     600
     601_pgcd_end:
     602    Add     r2 , r4 , r0    ; valeur de retour
     603    Jr      r31
     604}}}
     605
     606Transformer ce code de telle façon qu'il puisse être exécuté sur le processeur Mips pipeline à 5 étages.
     607
     608
     609'''''Solution 12 :'''''
     610
     611Il suffit d'ajouter une instruction NOP après chaque branchement.
     612{{{
     613#!asm
     614_pgcd:
     615    Beq     r4 , r5 , _pgcd_end
     616    Nop
     617
     618_pgcd_loop:
     619    Sltu    r8 , r4 , r5    ; a < b
     620    Beq     r8 , r0 , _pgcd_else
     621    Nop
     622    Subu    r5 , r5 , r4
     623    J       _pgcd_endif
     624    Nop
     625
     626_pgcd_else:
     627    Subu    r4 , r4 , r5
     628_pgcd_endif:
     629    Bne     r4 , r5 , _pgcd_loop
     630    Nop
     631
     632_pgcd_end:
     633    Add     r2 , r4 , r0    ; valeur de retour
     634    Jr      r31
     635    Nop
     636}}}
     637
     638
     639Analyser l'exécution de la boucle sur le processeur Mips à l'aide d'un schéma simplifié, dans le cas où le `if` (du code source) réussit, puis dans le cas où le `if` échoue.
     640
     641
     642'''''Solution 12 :'''''
     643
     644[[Image(htdocs:/corrige/Seance3/S3_corrige_Q12_a.svg)]]
     645
     646Cas où le `if` réussit :
     647
     648[[Image(htdocs:/corrige/Seance3/S3_corrige_Q12_b.svg)]]
     649
     650Cas où le `if` échoue :
     651
     652[[Image(htdocs:/corrige/Seance3/S3_corrige_Q12_c.svg)]]
     653
     654
     655
     656
     657Calculer le nombre de cycles nécessaires à l'exécution d'une itération de la boucle dans le cas ou le `if` réussit.
     658
     659
     660'''''Solution 12 :'''''
     661
     662Il faut 9 cycles pour une itération si le `if` réussit.
     663
     664
     665Calculer le nombre de cycles nécessaires à l'exécution d'une itération de la boucle dans le cas ou le `if` échoue.
     666
     667
     668'''''Solution 12 :'''''
     669
     670Il faut 8 cycles pour une itération si le `if` échoue.
     671
     672
     673Sachant que dans un cas sur deux le `if` échoue, calculer le CPI et le CPI-utile de la boucle.
     674
     675
     676'''''Solution 12 :'''''
     677
     678CPI = 1.214 cycle/instrution
     679
     680CPI_utile = 1.889 cycle/instrution utile
     681
     682