L'architecture pipe-line


[Previous]  [Next]  [Summary]
  1. Principe
  2. Problèmes
    1. Accès à la mémoire
    2. Dépendances entre registres
    3. Les branchements
    4. Les interruptions

1. Principe

Dans le cas des architectures classiques l'exécution des instructions présente un aspect très séquentiel. Il est cependant possible d'obtenir un certain recouvrement dans l'exécution d'instructions successives. L'architecture dite pipe-line généralise ce concept de recouvrement entre instructions.

Les premières machines commerciales mettant en oeuvre ce type d'architecture apparurent au début des années 60 avec l'IBM 360/91 en 1964. Les activités au sein de l'unité centrale sont organisées comme sur une chaîne de montage : on décompose l'unité de commande chargée de la lecture des instructions, de leur décodage, de leur exécution, ... en plusieurs modules fonctionnellement "disjoints". Chacun de ces modules travaille en parallèle avec les autres. On commence ainsi le traitement d'une nouvelle instruction avant que la précédente ne soit terminée, ce qui crée un flot continu en entrée de chacun des modules. Ce recouvrement est source de nombreuses difficultés dans l'exécution des instructions. On ne peut en effet jamais être sžr qu'une instruction est terminée avant que la suivante ne s'exécute. Vues les difficultés engendrées, ces machines sont très rarement programmées directement en langage d'assemblage par les utilisateurs. Elles sont le plus souvent dotées d'un compilateur C qui prend en charge tous ces problèmes avec une efficacité proche de celle qui pourrait être obtenue par un bon programmeur.

Considérons une architecture pipe-line à quatre étages inspirée de celle du microprocesseur TMS320C30 de Texas Instruments. Nous allons supposer que les quatre étages correspondent aux phases :

  1. de lecture de l'instruction (fetch) et mise à jour du compteur ordinal,
  2. de décodage (decode) et calcul de l'adresse de l'opérande,
  3. de lecture de l'opérande en mémoire (s'il y a lieu) (read),
  4. et d'exécution (execute) dans laquelle :
    1. soit on lit un opérande dans un registre, on exécute l'opération et on écrit le résultat dans un registre,
    2. soit on écrit dans la mémoire le résultat de l'instruction qui précède.
Considérons l'exécution de trois instructions I1, I2, et I3. On représentera le fonctionnement de la machine par un diagramme de la forme :

    <--------------- cycle majeur -------------->
    <-mineur->
       T     ->  2T     ->  3T     ->  4T      ->  5T
I1     Fetch ->  Decode ->  Read   ->  Execute
I2               Fetch  ->  Decode ->  Read    ->  Execute
I3                          Fetch  ->  Decode  ->  Read
CO     n         n+1        n+2        n+3         n+4
où CO représente le contenu du compteur ordinal. Si on appelle cycle mineur le cycle de base de la machine et cycle majeur la durée d'une instruction, on voit qu'une instruction est fournie en sortie du pipe-line chaque cycle mineur. Ce cas de fonctionnement estévidemment idéal. Nous allons recenser dans ce qui suit les principaux problèmes posés par ce type d'architecture.

2. Problèmes

Les principaux problèmes rencontrés dans les architectures pipe-line sont liés aux accès à la mémoire, aux conflits de dépendance entre registres, aux branchements et au traitement des interruptions et exceptions. Tous ces problèmes peuvent être résolus soit matériellement (techniques basées sur un marquage de registres), soit par logiciel (utilisation de compilateurs qui se chargent d'insérer des instructions nop ou de permuter des instructions du programme). La programmation en assembleur nécessite beaucoup de soin, les résultats pouvant être imprévisibles si l'on ne tient pas compte de la spécificité de ce type de processeur.

2.1. Accès à la mémoire

Les conflits d'accès à la mémoire trouvent leur origine dans plusieurs situations :

Exemple : on considère la suite d'instructions suivante :

I1    mov r0,(r1)	écriture en mémoire
I2    mov (r2),r3	lecture dans le même banc mémoire
On suppose que deux accès ne peuvent se faire simultanément dans le même cycle. Le diagramme correspondant est le suivant :

	T	2T	3T	4T	5T	6T	7T	8T
I1	Fetch	Decode	Read	Execute	...	...	...	...
I2		Fetch	Decode	...	Read	Execute		...
I3			Fetch	...	Decode	Read	Execute	
I4					Fetch	Decode	Read	
	n	n+1	n+2	n+2	n+3	n+4	n+5	
Le conflit apparaît dans le cycle noté 4T et est résolu ici en insérant un cycle supplémentaire. On dit que l'on a une pénalité de 1.

Exemple : dans le microprocesseur TMS320C30(1) la mémoire autorise deux accès simultanés dans le même cycle. On a ainsi un conflit lorsqu'une opération d'écriture est suivie de deux opérations de lecture. Soit le progamme :

I1       sti r0,*ar1    écriture en mémoire
I2       ldi *ar2,r1    lecture dans le même banc mémoire
I2'||    ldi *ar3,r2    lecture simultanée (instruction parallèle)
Les deux instructions ldi sont codées sur le même mot mémoire de 32 bits. On note cette instruction ldi||ldi. Le diagramme correspondant est le suivant :
	T	2T	3T	4T	5T	6T	7T
sti	Fetch	Decode	Read	Execute	nop	...	...
ldi||ldi		Fetch	Decode	Read	Read	Execute	...
I3			...	Fetch	...	Decode	
I4					...	Fetch	
	n	n+1	n+1	n+2	n+2	n+3	
On a aussi conflit lorsque deux opérations d'écriture sont suivies d'une lecture.

2.2. Dépendances entre registres

Cette dépendance intervient lorsque le contenu d'un même registre est manipulé par deux instructions successives. Considérons en exemple la séquence d'instructions :

I1    mov    #10,r0    on charge r0 avec 10 (dans la phase d'exécution)
I2    mov    (r0),r2   on charge r2 avec la case mémoire d'adresse r0
                       le calcul d'adresse est fait pendant la phase de
                       décodage
Le diagramme correspondant est le suivant :
	T	2T	3T	4T	5T	6T	7T	8T
I1	Fetch	Decode	Read	Execute	...	...	...	...
I2		Fetch	Decode	...	Decode	Read	Execute	...
I3			Fetch	...	...	Decode	Read
I4						Fetch	Decode
	n	n+1	n+2	n+2	n+2	n+3	n+4
On a ici une pénalité de 2. Cependant, l'insertion de cycles de retard n'est pas la seule solution. Ainsi, dans l'architecture SPARC, les pénalités peuvent êtreévitées en utilisant une technique dite de bypass. Cette technique permet d'anticiper sur la phase de décodage de l'instruction qui suit. Elle nécessite cependant que la détection de dépendance soit faite pendant la phase fetch de cette dernière.

2.3. Les branchements

L'exécution de branchements pose un problème en raison de la présence d'autres instructions dans le pipe. Les machines pipe-line offrent généralement deux types de branchements : les branchements simples dans lesquels le pipe est vidé avant exécution du branchement, et les branchements retardés (delayed branches) pour lesquels on force l'exécution des k instructions qui suivent ce branchement. Une bonne utilisation de ces branchements permet d'optimiser le fonctionnement du processeur. Prenons pour exemple le branchement simple Branch m. Le séquencement est le suivant :

	T	2T	3T	4T	5T	6T	7T
Branch	Fetch	Decode	Read	Execute	...	...	...
I2		Fetch	...	...	...	...	...
I3			...	...	...	...	...
Icible				...	Fetch	Decode	
I5						Fetch	
	n	n+1	n+1	n+1	m	m+1	
Les branchements retardés, quant à eux, ne sont généralement pas utilisés pour la programmation de boucles. Pouré;viter tout problème de conflit les interruptions sont souvent inhibées jusqu' à fin d'exécution des k instructions qui suivent. Exemple de branchement retardé BranchD m avec k=3 :

	T	2T	3T	4T	5T	6T	7T
BranchD	Fetch	Decode	Read	Execute	...	...	...
I2		Fetch	Decode	Read	Execute	...	...
I3			Fetch	Decode	Read	Execute	...
				Fetch	Decode	Read
Icible					Fetch	Decode
	n	n+1	n+2	n+3	m	m+1
Le cas des branchements conditionnels est difficile à résoudre. Pour limiter les pénalités on utilise plusieurs techniques : utilisation de bits de prédiction ou de cache de branchement ou des deux. Une autre technique est dite technique du bit d'annulation (annul bit). Cette technique est mise en oeuvre dans le TMS320C30 par l'entremise des instructions bnegat et bnegaf. Celles-ci, lorsque la condition est remplie (négatif vrai ou faux resp.), provoquent l'inhibition de la phase d'exécution des trois instructions qui suivent.

Exemple :
    ldi        *ar1,r0
    bnegat     suite
    addi       *++ar2,r3    (ar2 est incrémenté)
    nop
    nop
suite:
Si le résultat est négatif (on effectue le branchement), le registre ar2 est tout de même modifié (phase de décodage) et la donnée lue. Par contre r3 n'est pas modifié puique la phase d'exécution n'est pas mise en oeuvre.

2.4. Interruptions

Lorsqu'il y a interruption, les instructions qui sont déj à dans le pipe-line sont exécutées. Nous avons vu le cas particlier du branchement retardé dans lequel les interruptions sont inhibées jusqu' à ce que les k instructions qui suivent soient exécutées.

Sur certaines machines, lorsqu'une interruption intervient dans le cycle de lecture d'une instruction, celle-ci peut être exécutée ou annulée selon le stade auquel le processeur est arrivé dans ce cycle. Dans d'autres, la décision est prise pendant le cycle de décodage. Dans ce dernier cas, si l'instruction est annulée, elle devra être relue après exécution du programme d'interruption.


(1)Texas Instr., "320C30 User's Manual"

[Top] [Previous]  [Next]  [Summary]