Exercices sur la structure des ordinateurs, Exercices de Application informatique. Ecole des Ingénieurs de la Ville de Paris
Christophe
Christophe3 March 2014

Exercices sur la structure des ordinateurs, Exercices de Application informatique. Ecole des Ingénieurs de la Ville de Paris

PDF (226.2 KB)
6 pages
714Numéro de visites
Description
Exercices d’informatique sur la structure des ordinateurs - exercices d'architecture. Les principaux thèmes abordés sont les suivants: Conversions, Jeu d'instructions, Traduction en assembleur MIPS, Exécution pipelinée, ...
20points
Points de téléchargement necessaire pour télécharger
ce document
Télécharger le document
Aperçu3 pages / 6
Ceci c'est un aperçu avant impression
Chercher dans l'extrait du document
Ceci c'est un aperçu avant impression
Chercher dans l'extrait du document
Aperçu avant impression terminé
Chercher dans l'extrait du document
Ceci c'est un aperçu avant impression
Chercher dans l'extrait du document
Ceci c'est un aperçu avant impression
Chercher dans l'extrait du document
Aperçu avant impression terminé
Chercher dans l'extrait du document

Exercices d'architecture Denis Barthou, ENSEIRB 2010-2011

1. Conversions

• Convertir en binaire sur 8 bits, en complément à 2, les nombres suivants: -65, -70 • Poser et calculer en binaire sur 8 bits en complément à 2 le calcul -65-70. Le résultat est-il

positif, négatif ? Expliquez la valeur du résultat. • Quelle est la valeur en décimal du nombre flottant sur 32 bits suivant ?

00100000011100000000000000000001 Vous pouvez l'écrire avec des puissances de 2.

2. Jeu d'instructions On considère une machine à 16 registres pour représenter les entiers: r0 jusqu'à r15, et 16 registres pour représenter les flottants: f0 jusqu'à f15. Son jeu d'instruction est donné par la table suivante, avec ri, rj, rk pouvant être n'importe lequel des registres entiers, fi et fj, fk n'importe lequel des registres flottants. r0 vaut toujours 0. Les registres sont tous des registres 32 bits.

Instruction Détail

OP ri,rj,rk ri ← rj OP rk avec OP une opération parmi add, sub, mul, div, and, or, xor.

FOP fi,fj,fk fi ← fj FOP fk avec FOP une opération flottante parmi addf, subf, mulf, divf. move ri,rj ri ← rj

movef (ri,rj,4),fk Valeur à l'adresse ri+rj*4 ← fk movef fi,(rj,rk,4) fi ← valeur à l'adresse rj+rk*4

move (ri),rj Valeur à l'adresse ri ← rj move ri,(rj) ri ← valeur à l'adresse rj

jeq ri,rj,n Fait un branchement à l'adresse n+adresse courante si ri == rj. Sinon continue l'exécution. n est une constante entière signée sur 5 bits.

• Proposer un codage de toutes ces instructions qui minimise le nombre de bits nécessaires.

3. Traduction en assembleur MIPS Traduire en assembleur MIPS le programme C suivant:

for (i=0; i<50; i++) { if (x !=2) if (y != 3) x=x*y+A[i]; else y=x*A[i]; A[i+1] = A[i]+1; } On supposera que x,y et A correspondent à des labels en mémoire (des adresses). Les valeurs des variables x et y seront placées et gardées dans des registres.

docsity.com

4. Exécution pipelinée On considère le code suivant MIPS:

add $1, $2, $3 add $5, $2, $3 sub $12, $4, $3 sw ($2), $5 add $5, $12, $11 lw $8, ($5)

On supposera, comme en cours, que l'architecture MIPS est pipelinée, avec 5 étages (qu'on notera IF, ID, EX, MEM, WB) et qu'une instruction seulement est commencée chaque cycle.

• Ecrire le diagramme de temps montrant à quel étage du pipeline se trouve chaque instruction en fonction du cycle d'exécution (sans tenir compte des dépendances). Quelles sont les dépendances entre instructions ?

• Corriger le diagramme précédent en supposant que l'architecture n'a pas de mécanisme de forwarding. En combien de cycles ce programme s'exécute-t-il ?

• Même question, en supposant cette fois que le chemin des données dispose de forwarding entre tous les étages du pipeline.

5. Pipelinessuperscalaires On considère une architecture pipelinée avec 10 étages. Chaque étage est traversé en 1 cycle.

• Pour exécuter 800 instructions, en supposant que cela ne provoque pas de stall, combien de cycles sont nécessaires pour leur exécution ?

• En supposant qu'une instruction sur 8 provoque un stall d'un cycle, en combien de cycles s'exécutent les 800 instructions ? Quel pourcentage du temps total d'exécution est passé dans les stalls ?

On considère maintenant que l'architecture est pipelinée sur 10 étages et superscalaire, prenant 4 instructions par cycle. Mêmes questions.

6. Caches On considère un processeur avec un cache 2-associatif, write allocate, d'une taille de 16Ko, et des lignes de 8 octets chacune. Le cache utilise une politique de remplacement LRU. On considère le code suivant

for (i=0; i<1000; i++) A[i] = B[i] + B[i+2]

avec A et B des tableaux d'entiers sur 32 bits. Le tableau A commence à l'adresse 0 et le tableau B à l'adresse 8000. On supposera que les accès se feront dans l'ordre: B[i], B[i+2] puis A[i] pour chaque itération i.

• Montrez, pour les 9 premiers accès, quels sont les hits/miss sur les 2 premiers sets du cache. • Combien de hit et de miss se produisent pendant l'exécution de la boucle ? Justifiez votre

réponse. • Que se passe-t-il si le cache est direct map ? • On ajoute maintenant un mécanisme de prefetch qui, lorsqu'il se produit un miss, charge la

ligne de cache suivante. Montrez, pour les 9 premiers accès, quels sont les hits/miss sur les 3 premiers sets du cache.

docsity.com

Correction des exercices d'architecture Denis Barthou, ENSEIRB 2010-2011

1. Conversions -65-70=-135, c'est un nombre en dehors de l'intervalle représentable en complément à 2 sur 8 bits, sa valeur absolue est trop grande, il va y avoir un overflow.

-65 → 01000001 +1 = 10111111

-70 → 01000110 +1 = 10111010

Leur somme donne : 01111001. C'est un nombre positif à cause de l'overflow.

Le nombre flottant est 0 01000000 1110000000 0000000000 001 Son signe est positif, son exposant est 64-127=-63 et sa valeur est: vaut (1+2-1+2-2+2-3+2-23).2-63

2. Jeu d'instructions Chaque registre a besoin de 4 bits. Les instructions FOP, OP, movef (les deux types) ont donc 12 bits pour les registres. Ces instructions sont au nombre de 13, c'est à dire qu'il faut 4 bits de plus pour pouvoir les distinguer entre elles par leur opcode. Ca fait en tout, au minimum, 16 bits pour une instruction. Montrons que 16 bits suffisent pour coder toutes les instructions.

Sur les 16 valeurs possibles d'opcode sur 4 bits, 13 sont utilisées par les instructions précédentes.

Pour les autres instructions move (3), 8 bits sont nécessaires pour les registres. On peut donc prendre pour elles le même opcode (0000 par exemple) et le compléter sur les 4 bits suivants.

Pour le jeq, 13 bits sont nécessaires pour coder les deux registres et la constante sur 5 bits. Ca veut dire que jeq ne devra se distinguer des autres instructions que grâce aux 3 premiers bits de l'opcode.

Prenons par exemple pour jeq l'opcode 001 (ca revient à dire que pour les autres instructions, les 4 premiers bits d'opcode 0010 et 0011 ne sont plus autorisés).

On peut donc prendre pour les opérations:

add → 0001 sub → 0100 mul → 0101 div → 0110 and → 0111 or → 1000 xor → 1001

addf → 1010 subf → 1011 mulf → 1100 divf → 1101 , movef → 1110 et 1111 (pour les deux formes).

3. Traduction en asm MIPS add $t0,$0,50

add $t1,$0,$0

lw $t2,(x)

lw $t3,(y)

add $t4,$0,A

L: lw $t6,($t4) // $t6 = A[i]

sub $t7, $t2, 2

beq $t7,$0,Endif // x-2 == 0

sub $t5,$t3,3

docsity.com

beq $t5,$0,Else // y-3 ==0

mul $t2,$t2,$t3 // x = x*y

add $t2,$t2,$t4 // x = x+A[i]

j Endif

Else: mul $t3,$t3,$t6 // y = y*A[i]

Endif: add $t6,$t6,1 // $t6 = A[i]+1

add $t4,$t4,4

sw ($t4),$t6 // A[i+1] = A[i]+1

sub $t1,$t1,1

bne $t1,$t0, L

4. Pipeline Dans cette correction, les diagrammes de temps ne sont pas réalisés. 1: add $1, $2, $3 2: add $5, $2, $3 3: sub $12, $4, $3 4: sw ($2), $5 5: add $5, $12, $11 6: lw $8, ($5) Les dépendances sont 2 → 5 (WAW), 2 → 6 (RAW) , 2 → 4 (RAW), 3 → 5 (RAW), 5 → 6 (RAW). En pipelinant sans tenir compte des dépendances, la dépendance 2 → 5 est vérifiée (dépendance entre étages WB), la 2 → 6 également (entre WB et ID 4 cycles après). Les autres posent problème.

Sans tenir compte des dépendances, l'exécution prendrait 6+4=10 cycles. Avec les dépendances, sans forwarding, les dépendances sont entre les étages WB (écriture du registre) et ID (lecture du registre). Au mieux, il faut que l'écriture dans le registre se fasse au même cycle que sa lecture. 2 → 4 contraint 1 cycle de stall (et règle aussi la 3 → 5). 5 → 6 nécessite 3 cycles de stall. L'exécution prend donc 10+1+3 cycles.

Avec forwarding, les dépendances 2 → 4 et 3 → 5 ne nécessitent plus de stall. La sortie de l'étage EX stockée dans EX/MEM puis MEM/WB le cycle suivant est propagée dans l'ALU, etage EX au début du cycle d'après. La dépendance 5 → 6 (entre le EX et le MEM) ne nécessite pas non plus de stall. La valeur de sortie de l'ALU est stockée dans EX/MEM, puis dans MEM/WB pour être finalement propagée en entrée de la mémoire. L'exécution prend 10 cycles.

5. Pipelines superscalaires

• Pour exécuter 800 instructions, en supposant que cela ne provoque pas de stall, il faut 800+10-1 cycles, soit 809 cycles.

• En supposant qu'une instruction sur 8 provoque un stall d'un cycle, en combien de cycles s'exécutent les 800 instructions ? 800*(1+1/8)+10-1 = 909 cycles.Quel pourcentage du temps total d'exécution est passé dans les stalls ? A peu près 11% du temps.

On considère maintenant que l'architecture est pipelinée sur 10 étages et superscalaire, prenant 4 instructions par cycle. Ca prend alors 200+10-1 cycles, soit 209 cycles (sans stall). Avec stall, un cycle sur 2, les 4 instructions lancées font un stall. Donc avec stall, il faut 200*(1+1/2)+9 = 309 cycles. Ca fait maintenant 32% du temps passé dans les stalls.

docsity.com

6. Caches Pour un cache k-associatif, avec des lignes de cache de L octets et une taille totale de cache de T octets, il y a T/(L*k) sets. Une adresse adr est placée dans une ligne du set numéro:

adr/L mod T/(L*k). Combien de sets dans le cache ? Chaque ligne a 8 octets. 2 lignes par set (cache 2 associatif), donc 16 octets/set. Comme le cache fait 16Ko, il y a donc 1000 sets. L'adresse de A[i] est 0+4*i. Le set dans lequel va A[i] est (0 + 4*i)/8 mod 1000. Le set dans lequel va B[i] est (8000+4*i)/8 mod 1000. B[i] et B[i+2] ne sont pas dans le même set. A[i] et B[i] sont dans le même set.

Pour les 9 premières itérations, Acces B[0]: miss → B[0], B[1] mis dans une ligne du set 0, B[2]: miss → B[2], B[3] mis dans une ligne du set 1 A[0]: miss → A[0], A[1] mis dans deuxieme ligne du set 0 (le cache est write allocate) B[1]: hit B[3]: hit A[1]: hit B[2]: hit B[4]: miss → B[4], B[5] mis dans ligne du set 2 A[2]: miss → A[2], A[3] mis dans deuxieme ligne du set 1

Pour les itérations qui suivent, ca se répète: pour une itération i paire, i=2k,

• B[2k] est dans le set numéro k, déjà accédé lors de l'itération i-2. L'accès B[i+2] est un miss car dans le set k+1 (jamais accédé avant). B[2k+2] et B[2k+3] sont mis dans le set k+1.

• l'accès à A[i] est un miss car aucun élément de A n'est encore dans le set k. Il charge alors A[2k] et A[2k+1] utilisé l'itération suivante.

Pour une itération i impaire, i=2k+1 • B[2k+1] est dans le set k, c'est un hit • B[2k+2] est dans le set k+1, c'est un hit (placé dans ce set l'itération d'avant). • A[2k+1] est un hit.

Donc pour chaque itération paire, on fait 2 miss. Pour chaque itération impaire, on fait 0 miss. Pour 1000 itérations, il y a donc 500*2 miss, plus les miss lors de la première itération (itération paire avec 3 miss). Ca fait donc 1001 miss. La boucle a 1000 itérations qui balaient les set 0 à 999 et lors des deux dernières itérations, on accède à nouveau au set 0. Le comportement reste toutefois identique, car ce sont les données les plus anciennement accédées (ici dans les lignes B[0], B[1] et A[0], A[1]) qui sont éjectées du cache (LRU).

Si le cache est direct map, A[i] est alors dans la ligne de cache (0+4*i)/8 mod 2000. B[i] est dans la ligne (8000+4*i)/8 mod 2000. A[i], B[i], B[i+2] sont tous sur des lignes de cache différentes. Même comportement du point de vue des miss/hits que le cas 2-associatif.

Dans le cas du prefetch: Acces B[0]: miss → B[0], B[1] mis dans une ligne du set 0, B[2] et B[3] mis dans une ligne du set 1. B[2]: hit A[0]: miss → A[0], A[1] mis dans deuxieme ligne du set 0, A[2], A[3] dans la deuxieme ligne du

set 1 B[1]: hit B[3]: hit

docsity.com

A[1]: hit B[2]: hit B[4]: miss → B[4], B[5] dans une ligne du set 2, B[6], B[7] dans une ligne du set 3 A[2]: hit Le prefetch mis en place (attention, d'autres stratégies de prefetch sont possibles) évite de faire les miss sur la ligne suivante → 2 fois moins de miss au total.

docsity.com

commentaires (0)
Aucun commentaire n'a été pas fait
Écrire ton premier commentaire
Ceci c'est un aperçu avant impression
Chercher dans l'extrait du document
Docsity n'est pas optimisée pour le navigateur que vous utilisez. Passez à Google Chrome, Firefox, Internet Explorer ou Safari 9+! Téléchargez Google Chrome