Vous êtes sur la page 1sur 13

Enseignant : Mehdi JEMAI I.S.E.T.

Kef 2023/2024

Chapitre 4 : Les techniques d’optimisation

1 Introduction

Vu que la rapidité d’exécution est très importante dans les processeurs DSP,
l’optimisation d’un programme dédiée à un DSP est une étape très importante qui permet
d’avoir des gains de temps considérables dans l’exécution du programme.

2 Gestion des chemins croisés (Data cross path and Adress cross path)
Pour augmenter les performances d’un processeur, l’augmentation de la fréquence
d’horloge et du nombre d’unités de calcul est la solution la plus évidente. Cependant
lorsque le nombre d’unités de calcul dépasse une unité, le fait d’utiliser plusieurs unités en
parallèle permet une optimisation accrue du programme. Les figures 1, 2 et 3 représentent
le plan des connexions qui existent entre les registres A, B et les unités de calcul
correspondantes.

Figure 1 – Chemin des interconnexions de la partie A et B

1
Enseignant : Mehdi JEMAI I.S.E.T.Kef 2023/2024

Figure 2 – Chemin des interconnexions de la partie A

Figure 3 – Chemin des interconnexions de la partie B

2
Enseignant : Mehdi JEMAI I.S.E.T.Kef 2023/2024

Remarque :

– que ce soit dans la partie A ou B, les connexions entre les registres (A ou B) et les unités
correspondantes .L, .S et .M sont spécifique pour chaque unité. Ceci implique que chaque
unité peut être utilisée avec les registres correspondants, sans créer de contraintes pour les
autres unités (.L, .S et .M),

– il existe dans chaque partie (A ou B) un chemin croisé reliant les registres d’une partie
(A ou B) aux unités de l’autre partie (B ou A respectivement). Ces deux chemins croisés
(cross path) sont notés 1X : chemin allant des registres B vers les unités .L1, .S1 et .M1, et
2X : chemin allant des registres A vers les unités .L2, .S2 et .M2,

– deux chemins croisés existent aussi au niveau des unités .D1 et .D2 pour les opérations
de chargement et de stockage croisé.

En assembleur, l’utilisation d’instructions qui seront exécutés en parallèle nécessite


l’utilisation de deux barres verticales "||". Ainsi, il est possible d’utiliser des instructions
parallèles dans la même partie (A ou B), ou entre les deux parties (A et B). Dans le
deuxième cas, on parle de chemins croisés (entre A et B). Le constructeur définit deux type
d’utilisation des chemins croisés ; les chemins croisés de donné "Data cross path" et les
chemins croisés d’adresse "Adress cross path".

2.1 Contraintes sur les instructions utilisant les mêmes unités


fonctionnelles

Deux instructions utilisant la même unité fonctionnelle (.L, .S ou .M) ne peuvent


pas être exécutées dans le même paquet d’exécution.

Exemple :

1-Le paquet d’exécution suivant est invalide:

ADD .S1 A0,A1,A2 ; .S1 est utilisée pour les deux instructions

|| SUB .S1 A3,15,A4 ;

2-Le paquet d’exécution suivant est valide :

ADD .L1 A0,A1,A2; Deux unités fonctionnelles différentes sont utilisés L1 et S1

|| SUB .S1 A3,15,A4 ;

3
Enseignant : Mehdi JEMAI I.S.E.T.Kef 2023/2024

2.2 Chemin croisé de donnée "Data cross path"

Contraintes sur les chemins croisés 1X et 2X Seule une unité (.S, .L, ou .M) par
chemin de donnée et par paquet d’exécution, peut lire une opérande depuis le registre
opposé à travers le chemin croisé (1X ou 2X) Par exemple, l’unité .S1 peut lire les
opérandes aussi bien depuis le registre A, ou bien elle peut lire une opérande depuis le
registre B en utilisant le chemin croisé 1X et la deuxième opérande depuis le registre A.
L’utilisation du chemin croisé est notée par X, suivant le nom de l’unité fonctionnelle dans
la syntaxe de l’instruction (comme pour .S1X).

Exemple :

1- Le paquet d’exécution suivant est invalide parce que le chemin croisé 1X est utilisé
pour deux opérandes différentes du registre B :

MVD .S1X B0,A0 ; Invalide: les instructions utilisent le chemin

|| MVD .L1X B1,A1 ; croisé 1X avec 2 registres B différents

2- Le paquet d’exécution suivant est valide parce que toute les utilisations du chemin
croisé 1X sont pour la même opérande du registre B, et toute les utilisations du
chemin croisé 2X sont pour la même opérande du registre A.

ADD .L1X A0,B1,A1 ; les instructions utilisent les chemins croisés 1X et 2X

|| MPY .M2X B4,A4,B2 ;

2.3 Chemin croisé d’adresse "Adress cross path"

Contraintes sur les opérations de chargement et de stockage Les instructions de


stockage et de chargement utilisent un pointeur d’adresse depuis un registre pour
(stocker/charger) (vers/depuis) un autre registre. Deux opérations de chargement/stockage
qui utilisent le même registre source/destination ne peuvent pas être exécutées dans le
même paquet d’exécution. L’adresse du registre doit être dans le même coté que l’unité .D
utilisée.

Exemple :

1- Le paquet d’exécution suivant est invalide :

LDW .D1 *A0,A1 ; \ L’unité .D2 doit utiliser le registre d’adresse depuis les registres B

|| LDW .D2 *A2,B2 ;

4
Enseignant : Mehdi JEMAI I.S.E.T.Kef 2023/2024

2- Le paquet d’exécution suivant est valide :

LDW .D1 *A0,A1 ; \ Les registres d’adresse sont corrects

|| LDW .D2 *B0,B2 ; /

De la même façon, un chargement depuis ou un stockage vers un même registre n’est pas
valide dans un même paquet d’exécution.

1- Le paquet d’exécution suivant est invalide :

LDW .D1 *A4,A5 ; \ Chargement depuis et stockage vers un même registre

|| STW .D2 A5,*B4 ; /

2- Le paquet d’exécution suivant est valide :

LDW .D1 *A4,A5 ; \ Chargement depuis et stockage vers différent registres

|| STW .D2 A6,*B4 ; /

2.3.1 Contraintes sur les opérations de lectures et d’écriture

a- Contraintes sur la lecture des registres


Le DSP n’accepte pas plus de quatre lectures sur le même registre durant un même
cycle. Les registres conditionnels ne sont pas inclus dans ce comptage.

1- Les paquet d’exécution suivant sont invalides :

MPY .M1 A1,A1,A4 ; cinq lectures du registre A1

|| ADD .L1 A1,A1,A5 ;

|| SUB .D1 A1,A2,A3 ;

MPY .M1 A1,A1,A4 ; cinq lectures du registre A1

|| ADD .L1 A1,A1,A5 ;

|| SUB .D2x A1,B2,B3 ;

2- Le paquet d’exécution suivant est valide :

MPY .M1 A1,A1,A4 ; seulement quatre lectures de A1

|| [A1] ADD .L1 A0,A1,A5 ; la condition sur A1 n’est pas prise en compte dans le calcul

|| SUB .D1 A1,A2,A3 ;

5
Enseignant : Mehdi JEMAI I.S.E.T.Kef 2023/2024

b- Contraintes sur l’écriture sur les registres

Deux instructions ne peuvent pas écrire sur le même registre durant le même cycle.

1- Le paquet d’exécution suivant est invalide :

ADD .L2 B5,B6,B7 ; \ écriture sur le même registre durant le même cycle

|| SUB .S2 B8,B9,B7 ; /

2- Le paquet d’exécution suivant est valide :

ADD .L2 B5,B6,B7 ;

|| SUB .S2 B8,B9,B10 ;

c- Contraintes sur les instructions successives

Lors de l’écriture d’un code assembleur, chaque ligne de code correspond à un


cycle machine. Ceci crée des contraintes lors de l’utilisation d’instructions qui nécessitent
plus d’un cycle machine pour s’exécuter. Soit les lignes de codes suivants écrits en
assembleur :

MPY .M1 A0,A1,A2; \ erreur, deux écritures sur le même registre

ADD .L1 A4,A5,A2; /

SUB .L1 A0,A1,A2; \ correct, écriture sur deux cycles différents

ADD .L1 A4,A5,A2; /

3- L’optimisation pipeline

L’optimisation pipeline est le processus permettant de manipuler le code afin d’avoir un


temps d’exécution plus rapide, et une plus petite taille du code. D’où l’utilisation les
ressources disponibles du DSP pour obtenir un code en pipeline efficace. Le but est
d’utiliser les huit unités fonctionnelles dans un seul cycle. Pour ce faire, un effort
supplémentaire de codage est requis en utilisant la technique de pipeline software.
L’optimisateur du compilateur peut être utilisé en ajustant les options du compilateur,
l’optimisation pourra atteindre alors des valeurs proches de 80%. L’optimisateur
assembleur de l’assembleur linéaire, quant à lui, ne gère que les instructions en parallèles
et le choix des registres puisque le code est écrit en assembleur. Il permet cependant
d’atteindre des niveaux de performance meilleur que l’optimisateur du compilateur. La
meilleure méthode reste la méthode manuelle, qui permet d’atteindre des performances de

6
Enseignant : Mehdi JEMAI I.S.E.T.Kef 2023/2024

100%. Dans la plupart des cas, il n’est pas nécessaire d’optimiser tout le code. Seule une
partie du code est optimisée, en général, c’est la partie qui contient le plus de calcul.

Les phases du pipeline sont divisées en trois étapes :

– recherche (fetch),

– décodage (decode),

– exécution (execute).

Figure 4– Illustration des trois étapes du pipeline

Selon le technique pipeline les instructions seront segmentées en étages. En effet, on a 3


instructions la chronologie d'exécutions sera comme celui-ci

Étage \ temps t1 t2 t3 t4 t5 t6 t7 t8 t9

Fetch F1 F2 F3

Decode D1 D2 D3

Execute E1 E2 E3

Exécution séquentielle

Étage \
t1 t2 t3 t4 t5 t6 t7 t8
temps

Fetch F1 F2 F3 F4 F5 … … …

Decode D1 D2 D3 D4 D5 … …

Execute E1 E2 E3 E4 E5 …

Exécution avec pipeline


Pour compléter le sujet du pipeline, on va voir à travers un exemple la manière dont
un DSP exécute des instructions en parallèle et pipelinées.

7
Enseignant : Mehdi JEMAI I.S.E.T.Kef 2023/2024

3-1-Codage manuel d’un pipeline


Les instructions sont toujours rapportées sous forme de huit (8) mots
simultanément. Ceci constitue un paquet-rapport (fetch packet) ou on appelle aussi un
paquet d’exécution. Le format de base d’un paquet rapport est illustré à la figure 5. Les
paquets rapport sont alignés sous formes de huit mots de 32 bits (256 bits), qui vont
transférer à travers le bus programme de largeur 256 bits. L’exécution d’une instruction
individuelle est partiellement contrôlées par un bit appelé "P" se trouvant dans chaque
instruction. Le bit "p" est toujours placé au bit zéro dans le code 32 bit d’une instruction. Il
détermine comment l’instruction s’exécute en parallèle avec une autre instruction. Le bit
"p" est scanné de gauche à droite (de la première adresse à la dernière adresse). Si le bit "p"
d’une instruction "i" est 1, alors l’instruction "i+1" s’exécutera en parallèle avec durant le
même cycle que l’instruction i. Si par contre le bit "p" d’une instruction "i" est 0, alors
l’instruction "i+1" s’exécutera un cycle après l’instruction i. Toutes les instructions qui
s’exécutent en parallèle constituent un paquet d’exécution. Un paquet d’exécution ne peut
pas contenir plus de huit (8) instructions. Chaque instruction dans un paquet d’exécution
doit utiliser une unité fonctionnelle différente. Vu qu’un paquet d’exécution ne peut pas
dépasser huit instructions, le dernier bit "p" dans un paquet rapport doit être toujours mis à
zéro. Et ainsi, chaque paquet rapport débute un nouveau paquet d’exécution. Ainsi en
fonction de la configuration des bits "p", il en résulte trois séquences d’exécution
différentes pour les huit instructions :

– totalement série,
– totalement parallèle,
– partiellement parallèle.

Figure 5– Fetch packet : format de base

Les exemples suivants montrent les conversions d’une séquence en "p" vers une exécution
cycle par cycle.

8
Enseignant : Mehdi JEMAI I.S.E.T.Kef 2023/2024

Exemple 1 : Exécution en série


Structure en "p" d’un paquet rapport totalement série et illustration sous forme
d’instructions (tableau 1).

Figure 6 – Fetch packet : instructions totalement série

Tableau 1 – 8 instructions exécutées séquentiellement

Exemple 2 : Exécution en parallèle

Structure en "p" d’un paquet rapport totalement parallèle (figure 7) et illustration


sous forme d’instructions (tableau 2).

Figure 7 – Fetch packet : instructions totalement parallèle

Tableau 2 – 8 instructions exécutées en parallèle

9
Enseignant : Mehdi JEMAI I.S.E.T.Kef 2023/2024

Exemple 3 : Exécution en parallèle partielle(ou partiellement série)

Structure en "p" d’un paquet rapport partiellement série (figure 8) et illustration sous forme
d’instructions (tableau 3).

Figure 8 – Fetch packet : instructions partiellement parallèle

Tableau 3– séquences d’exécutions pour un paquet rapport partiellement série

Soit le code assembleur suivant sera codé en série, parallèle et partiellement parallèle

10
Enseignant : Mehdi JEMAI I.S.E.T.Kef 2023/2024

4-Application
Afin de montrer comment optimiser un code, nous allons travailler sur l’exemple
d’un code de somme de produit :

N 1
y  n    h i .x i 
i 0

Afin d’implémenter l’équation précédente, La procédure est la suivante :

1. Charger les échantillons x[i],

2. Charger les coefficients h[i],

3. Multiplier x[i] et h[i],

4. Ajouter (x[i]*h[i]) au contenu de l’accumulateur,

5. Répéter les étapes 1) à 4) N-1 fois,

6. Sauvegarder le contenu de l’accumulateur dans y.

Les étapes 1 à 6 peuvent être traduites dans le code assembleur comme suit :

MVK .S1 N-1,B0 ; Initialiser le compteur de boucle


MVK .S1 0,A5 ; Initialiser l’accumulateur
Loop: LDH .D1 *A8++,A2 ; charger x[i]
LDH .D1 *A9++,A3 ; charger h[i]
NOP 4 ; retard de 5 cycles de LDH
MPY .M1 A2,A3,A4 ; multiplier x[i] et h[i]
NOP ; Delay de 2 cycles de MPY
ADD .L1 A4,A5,A5 ; ajouter "x [i]. h[i]" à l’accumulator
SUB .L2 B0,1,B0 ;
[B0] B .S1 loop ; boucler avec loop
NOP 5 ; Retard de 6 cycle de B
Afin d’optimiser le code, il faut :

1. Utiliser les instructions en parallèle,

11
Enseignant : Mehdi JEMAI I.S.E.T.Kef 2023/2024

2. Supprimer les NOPs,

Après utilisation d’instructions en parallèle et élimination de NOPs, le code devient :

loop LDH .D1 *A8++,A2;

|| LDH .D2 *B9++,B3;

SUB .L2 B0,1,B0 ;

[B0] B .S1 loop ;

NOP ;

MPY .M1x A2,B3,A4;

NOP ;

ADD .L1 A4,A5,A5;

3. Supprimer le bouclage (supprimer SUB et B : dérouler la boucle),


SUB et B utilisent au moins 2 cycles supplémentaires par itération. En enlevant la boucle
le code devient :

LDH .D1 *A8++,A2 ;Début iteration 1

12
Enseignant : Mehdi JEMAI I.S.E.T.Kef 2023/2024

|| LDH .D2 *B9++,B3

NOP 4

MPY .M1X A2,B3,A4 ;Utilisation du cross path

NOP

ADD .L1 A4,A5,A5

LDH .D1 *A8++,A2 ;Début iteration 2

|| LDH .D2 *B9++,B3

NOP 4

MPY .M1X A2,B3,A4

NOP

ADD .L1 A4,A5,A5

::

::

::

LDH .D1 *A8++,A2 ; Début iteration n

|| LDH .D2 *B9++,B3

NOP 4

MPY .M1X A2,B3,A4

NOP

ADD .L1 A4,A5,A5

4. Utiliser l’accès par mot ou double-mot au lieu de l’accès par byte ou moitié de mot.

13

Vous aimerez peut-être aussi