Cours 03 – LangageC

publicité
ELE-542
Systèmes ordinés en temps réels
Cours # 3
Langage C et temps réel
Jean-Marc Beaulieu et Bruno De Kelper
Site internet: http://www.ele.etsmtl.ca/academique/ele542/
Systèmes ordinés en temps réel
1
Qu’est ce qui influence le temps d’exécution
Matériel
Matériel
Programme
Compilateur
Compilateur
Processeur
Taille (8, 16, 32 bits)
Instructions
Pipeline, cache
Mémoire
Bus système
Programme
Optimisation du code
Déroulement de boucle
Utilisation de registres
« Inlining »
Instructions spéciales du CPU
Algorithmes
Choix des variables
Type des variables
Emplacement en mémoire
Choix des opérations
Algorithmes
Algorithmes
2
Systèmes ordinés en temps réel
1
Le matériel
Bus de données
Bus d’adresse
Mémoire
Processeur
Systèmes ordinés en temps réel
3
Le langage C pour le temps réel
—Ce qu’on veut analyser :
• En quoi le langage C aide-t-il à la conception temps réel ?
• Quelles sont les caractéristiques désirables pour le T.R ?
• En C, qu’est-ce qui influence le temps d’exécution ?
—Pourquoi le langage C ?
•
•
•
•
Les compilateurs sont très performants;
Le temps de développement est beaucoup plus court;
Beaucoup de développement déjà existant;
Portabilité d’une architecture à une autre.
Systèmes ordinés en temps réel
4
2
Architecture du programme
Systèmes ordinés en temps réel
5
Modularité en langage C
— La modularité permet de décomposer un projet en bloc plus
facile à gérer.
— En C, nous avons la notion de fonction et la notion de bloc de
code (code entre { }).
— Au plus haut niveau, l’approche consiste à découper le code
en utilisant plusieurs types de fichiers.
˜Identifier les fichiers sources (.c);
˜Identifier les fichiers d’en-têtes et d’inclusions (.h);
˜Identifier les fichiers de données et les fichiers
spéciaux.
Systèmes ordinés en temps réel
6
3
Sortes de fichiers
— Sortes de fichiers
• .c
˜Code source en C.
˜Le module principal doit contenir la définition
de la fonction main().
˜Permet d’exploiter la compilation séparée.
• .obj, .o
˜Code objet. Fonction compilée traduite en
assembleur mais non localisée en mémoire.
(adresse relative)
˜Code orienté selon un processeur cible.
˜Résultant de la compilation d’une source .c.
Systèmes ordinés en temps réel
7
Sortes de fichiers
• .h
˜Fichier d’inclusion et d’en-têtes;
˜Utilisation :
• #include <math.h> /*répertoire système*/
• #include ”math.h ” /*répertoires courants*/
˜Contient les déclarations de fonctions (prototype);
˜Contient les structures de données (typedef STRUCT);
˜Contient les définitions communes (#define PI 3.141592);
˜Contient les variables globales.
Systèmes ordinés en temps réel
8
4
Sortes de fichiers
• .lib
˜Bibliothèque;
˜Regroupement de fonctions compilées sous format objet
(.o);
˜Outil tlib pour construire et générer une bibliothèque.
• .exe (.hex)
˜Exécutable;
˜Contient un code compilé à charger en mémoire;
˜Comprend le code du programme et de tous ces modules,
localisés en mémoire;
˜Résultant de l’édition des liens (Linker).
Systèmes ordinés en temps réel
9
Processus de compilation
— Compilateur : Traduction en langage
.h
.h
.c
.h
.c
Compilateur
.lib
.o
.o
Linker
.exe
machine. Adresse relative. Laisse un espace
pour les appels de fonctions. Utilise les
prototypes des fonctions appelées pour
garder un espace. Étape lente
• Votre source appelle;
˜ fabs(float); /*nécessite l’entête dans
math.h*/
— Linker : Assemble toutes les portions de
code compilées. Place des adresses absolues.
Le code des fonctions provient de vos .o ou
des biblio .lib.
• Votre source a besoin du code compilé de
fabs(), alors il le prendra dans math.lib.
Systèmes ordinés en temps réel
10
5
Avantages et désavantages de la modularité
—Avantages :
• Masquage
˜Fonctionnement interne caché. Permet une description du
module en terme d ’entrée/sortie sans les détails internes.
• Interface par paramètres
˜La description des paramètres indique sur quelles données
la fonction va travailler.
• Traitement spécifique et restreint
˜Chaque module a une tâche spécifique.
• Division possible du travail
˜Chaque membre de l’équipe s’occupe d’un module.
Systèmes ordinés en temps réel
11
Avantages et désavantages de la modularité
• Auto-suffisance
˜Un module est complet en lui-même. Il peut être testé
séparément en lui fournissant des paramètres de
vérification.
• Compilation séparée
˜On peut recompiler que les sources modifiées avec des
utilitaires. (make, project)
• Réutilisation
˜On peut réutiliser les blocs dans un autre projet ou encore
les commercialiser avec seulement (.lib +.h)
—Les désavantages sont très faibles :
• Ralentissement causé par les accès mémoire
supplémentaires (appel de fonctions)
Systèmes ordinés en temps réel
12
6
Note sur la programmation
— Pour éviter …
• programme confus;
• difficile à déboguer;
• difficile à modifier ou à
adapter.
— Règles générales d’écriture de programme
• Indentation des blocs et des boucles
• Aération du code source
• En-tête de fonction
˜Description, paramètres E/S, structure, date, auteur)
• Commentaires
• Nom de variable significatif
Systèmes ordinés en temps réel
13
Réentrance
Et
Passage de paramètres
Systèmes ordinés en temps réel
14
7
Réentrance et récursivité
Quelques définitions :
—Réentrance
• Propriété d’une fonction qui peut être interrompue
et être appelée de nouveau dans la fonction de
traitement de l’interruption.
—Récursivité
•
Propriété d’une fonction qui s’appelle elle-même.
—Région critique ou atomique
•
Partie de code qui ne peut pas être interrompue.
Systèmes ordinés en temps réel
15
Réentrance et récursivité
En C, les conditions pour avoir une fonction réentrante sont :
1) La fonction utilise seulement des variables locales (sur la
pile)
-- Attention aux pointeurs;
2) La fonction appelle seulement des fonctions réentrantes;
3) La fonction utilise les variables non locales de façon
atomique. -- En C, les accès sont protégés par désactivation
des interruptions, sémaphores, etc...
Systèmes ordinés en temps réel
16
8
Passage de paramètres
— Il existe 2 grandes catégories pour le passage de
paramètres à une fonction.
— Par liste de paramètres
˜Passage par valeur;
˜Passage par référence.
— Par variables globales
Systèmes ordinés en temps réel
17
Passage par liste de paramètres
— Attention….
• Souvent les IRQ sont désactivées durant la copie des
paramètres sur la pile.
Augmente le temps de latence des interruptions
a
b
c
d
˜Prenons un exemple de fonction :
float moyenne(a, b, c, d);
˜une IRQ pourrait survenir au milieu du
transfert des paramètres sur la pile, et cette IRQ
pourrait modifier les valeurs a, b, c, d;
˜Alors on aura pour la fonction moyenne( ) des
nouvelles valeurs et des anciennes valeurs.
Systèmes ordinés en temps réel
18
9
Passage par variables globales
—Variables globales
• Visibles de tous les modules parce que définies à
l’extérieur;
• Possibilité de référer en mode d’adressage direct,
donc;
Plus rapide parce qu’elles ne passent pas par la pile;
• Pas nécessaire de désactiver les interruptions;
• Seule façon (sauf par registre) de transmettre un
paramètre à une routine d ’interruptions.
• DANGER
˜n’importe quel module peut modifier la valeur;
˜difficile à documenter
Systèmes ordinés en temps réel
19
Comparaison
— Quoi faire si on a plusieurs paramètres à transmettre à
une fonction ?
• Rendre toutes les variables globales :
peu pratique
• Transmettre tous les paramètres : lent, beaucoup d’accès pile
• Transmettre un pointeur sur une liste
oui, si les valeurs
sont placées à la suite en mémoire...
— En résumé...
• Si le temps est "moins" important ou crucial
¾ Liste de paramètres;
¾ Meilleur pour la modularité, encapsulation Æ entretien du code.
• Si le temps est très, très important
¾ Variable globale
• Si on doit transmettre à une routine d’IRQ
¾ Variable globale
Systèmes ordinés en temps réel
20
10
Les données
Systèmes ordinés en temps réel
21
Gestion de données
Outre les variables GLOBALES et LOCALES
Classes d'allocation (Un préfixe à la déclaration…)
Permet de spécifier l’endroit où sont emmagasinées les données
• Dans la région mémoire de la pile, le heap, les données, un registre;
•
•
•
•
•
Register
Static
Auto
Extern
Volatile
un registre du CPU sera attribué, si possible…;
une variable globale au fichier seulement….;
une variable locale est une auto par défaut...
pour partager une variable globale entre fichiers…
une variable qui est modifiée par des instructions
non apparentes
Exemple : variable modifiée dans une interruption
Systèmes ordinés en temps réel
22
11
Types de données
—Répertoire
• Le langage C possède un grand répertoire de
types disponibles au programmeur.
˜Plus facile de structurer les données;
˜Plus grand choix d’espace d’enregistrement;
• Exemple : La valeur du CAN 8 bits : unsigned char.
—Le C permet des opérations sur des types
différents.
• Mais la conversion implicite peut entraîner
une pénalité dans le temps d'exécution.
Systèmes ordinés en temps réel
23
Types de données
Systèmes ordinés en temps réel
24
12
Opérations sur des données
Dépend du processeur
— Les opérations ont des performances différentes selon
le type des données :
Dépend du processeur
RAPIDE
LENT
÷
double
float
long int
int
char
X
double
float
long int
int
char
+
double
float
long int
int
char
-
double
float
long int
int
char
long int
int
char
&
RAPIDE
Systèmes ordinés en temps réel
25
Opérations sur des données
Soit x,y,z : entiers 16 bits
2 opérations d’addition
zLSB = xLSB + yLSB
zMSB = xMSB + yMSB+ carry
Processeur
8 bits
2 cycles d’écriture
2 cycles de lecture
z = x+ y
1 cycle de lecture
1 cycle d’écriture
Processeur
16 bits
1 opération d’addition
z=x+y
Systèmes ordinés en temps réel
26
13
Types de données
—Conversion implicite des données
• En C, les 2 données d’une opération sont converties
au type le plus exigeant avant d’effectuer
l’opération. Ceci a pour conséquence :
• Temps d’exécution plus long *** en général ***;
• Mécanisme pas facile à prévoir;
Long double
double
• Exemple de problématique ( le 2 est pris comme un int, alors)
unsigned char resul, n = 5;
resul = 2 * n;
float
unsigned long int
long int
• Solution, la conversion explicite («casting»)
resul = (unsigned char)2 * n;
unsigned int
int
char
• Un autre exemple plus complexe :
*(int *)(0x0074) = (int) codec_interrupt;
short
Systèmes ordinés en temps réel
27
Valeurs logiques versus entiers
—Le langage C ne possède pas de type booléen, donc les opérations
sont faites avec des variables entières (ou char).
—Pour utiliser efficacement les ressources, on regroupe souvent
plusieurs booléens.
—Zéro = FAUX et non-zéro = VRAI
—Exemples :
Bits 15 - 11
Hours
Bits 10 - 5
Minutes
Bits 4 - 0
Seconds ÷ 2
MS/DOS packed representation of time.
7
RXC
6
TXC
5
UDRE
4
FE
3
DOR
2
PE
1
U2X
0
MPCM
Registre UCSRA du UART du ucontrôleur ATMega16
Réf. : Lewis, Chap. 3
Systèmes ordinés en temps réel
28
14
Deux types d’opérateurs : Booléens et binaires
Opérations
AND
OR
XOR
NOT
Décalage à
gauche
Décalage à
droite
Opérateur booléen Opérateur binaire
&&
&
||
|
non-supporté
^
!
~
non-supporté
<<
non-supporté
>>
Tester un bit
if ((bits
!= 0)
Test
6 */
if (bits&&64)
(1 <<
6)) /* /*
Test
dudu
bitbit
6 */
b7b6b5b4b3b2b1b0
Réf. : Lewis, Chap. 3
&
0b6000000
01000000
Systèmes ordinés en temps réel
29
Opérations sur les bits
Assigner un bit
bits = bits | (1 << 7) ;
b7b6b5b4b3b2b1b0
|
/* sets bit 7 */
10000000
1 b6b5b4b3b2b1b0
Remise à zéro d’un bit
bits &= ~(1 << 7) ;
Note :
Réf. : Lewis, Chap. 3
(1 << 7)
~(1 << 7)
/* resets bit 7 */
10000000
01111111
Systèmes ordinés en temps réel
30
15
Opérations sur les bits
Inverser un bit – XOR
bits ^= (1 << 6) ; /* inversion du bit 6 */
Attention à la taille par défaut des variables entières (int) selon
le compilateur/processeur
Si les int sont de 32 bits
0xFFFFFFFFL & ~(1 << 14) ⇒
0xFFFFFFFFL & ~(1L << 14)⇒
Si les int sont de 16 bits
FFFFBFFF (ok)
FFFFBFFF (ok)
0xFFFFFFFFL & ~(1 << 15) ⇒
0xFFFFFFFFL & ~(1L << 15)⇒
00007FFF (error)
FFFF7FFF (ok)
Réf. : Lewis, Chap. 3
Systèmes ordinés en temps réel
31
Utilisation des structures pour manipuler les bits
Exemple :
struct {
unsigned
Bits 15 - 11
Hours
seconds
minutes
hours
Bits 10 - 5
Minutes
Bits 4 - 0
Seconds ÷ 2
:5 ,
:6 ,
:5 ;
} time ;
time.hours = 13 ;
time.minutes = 34 ;
time.seconds = 18 / 2 ;
Réf. : Lewis, Chap. 3
Systèmes ordinés en temps réel
32
16
Exemple : Bits réservés mais inutilisés
typedef struct {
unsigned
CF
PF
AF
ZF
SF
TF
IF
DF
OF
:1,
:1,
:1,
:1,
:1,
:1,
:1,
:1,
:1,
:1,
:1,
:1,
:4 ;
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
Bit 0: Carry Flag
Bit 1: (unused)
Bit 2: Parity Flag
Bit 3: (unused)
Bit 4: Auxiliary Carry Flag
Bit 5: (unused)
Bit 6: Zero Flag
Bit 7: Sign Flag
Bit 8: Trap Flag
Bit 9: Interrupt Enable Flag
Bit 10: Direction Flag
Bit 11: Overflow Flag
Bits 12-15: (unused)
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
} PSW ;
Réf. : Lewis, Chap. 3
Systèmes ordinés en temps réel
33
Accès selon différents types – UNION
—Vous voulez accéder aux mêmes cases mémoires mais en utilisant
des types différents.
union {
unsigned long dd ;
unsigned short dw[2] ;
unsigned char db[4] ;
};
31
0
dd
dw[1]
db[3] db[2]
31
24 23
dw[0]
db[1] db[0]
16 15
87
0
Occupe le même espace en mémoire
Réf. : Lewis, Chap. 3
Systèmes ordinés en temps réel
34
17
Exemple : Structure et union de bits
typedef union {
struct {
char TXB8 :1,
RXB8 :1,
UCSZ2 :1,
TXEN :1,
RXEN :1,
UDRIE :1,
TXCIE :1,
RXCIE :1,
} Bits;
unsigned char Byte;
} USCRB ;
Réf. : Lewis, Chap. 3
/* Bit 8 : transmission
/* Bit 8 : réception
/* MSB de Taille de données
/* Activation du transmetteur
/* Activation du récepteur
/* Registre de donnée vide
/* Fin de transmission
/* Fin de réception
*/
*/
*/
*/
*/
*/
*/
*/
Exemple d’utilisation :
UCSRB.Byte = (char) 0x00;
UCSRB.Bits.TXEN = 1;
UCSRB.Bits.RXEN = 1;
Systèmes ordinés en temps réel
35
Accès aux ports d’entrées / sorties
Accès de type « I/O Mapped »
— Utilisation d’instructions spéciales (IN ou OUT)
ou de fonctions C [inportb() ou outportb()].
— Certains ports sont accessibles seulement en lecture ou en écriture.
— Plusieurs registres peuvent avoir la même adresse dans l’espace
des adresses E/S.
• Dans ce cas, la procédure d’accès est importante (ordre
d’accès, lecture/écriture, bit de sélection, …).
Exemple :
// lire contenu du registre de données, port série
COM3, 8250
carac_recu = inportb (0x03E8);
Systèmes ordinés en temps réel
36
18
Compilateur
Systèmes ordinés en temps réel
37
Techniques d’optimisation utilisées par les compilateurs
— Utilisation d’identités arithmétique
Utilise les identités arithmétique pour éliminer des opérations inutiles
tels que :
z = x + 1*y → z = x + y
z = 3*x + 0 → z = 3*x
— Réduction de force des opérations
Choisit les instructions les plus performantes, tel que
z = 8*x → z = x << 3
— Élimination de sous expressions communes
Regroupe des sous expressions communes, tel que
x = y + a*b
y = a*b + z
t = a*b
x=y+t
y=t+z
Systèmes ordinés en temps réel
38
19
Techniques d’optimisation utilisées par les compilateurs
— Utilisation de fonctions intrinsèque
Remplace des appels de fonctions par des « macro » insérées
directement à la place de l’appel de fonction.
— Pliage de constantes
Regroupe les constantes ensembles, tel que
z = 7*x*2 → z = 14*x
— Optimisation des parties invariantes des boucles
Extrait les parties des boucles qui ne changent pas, tel que
x = 100;
while (x > 0) {
x = x – y + z;
}
x = 100;
t = y + z;
while (x > 0) {
x = x + t;
}
Systèmes ordinés en temps réel
39
Techniques d’optimisation utilisées par les compilateurs
— Élimination des inductions dans les boucles
Élimination des calculs de « décalage » inutiles, tel que
for (i = 0; i < 10; i++)
a[i+2] = 1;
for (i = 2; i < 12; i++)
a[i] = 1;
— Utilisation de registres et de mémoire cache
Place les variables fréquemment utilisées dans des registres du
processeur ou dans la mémoire cache.
— Élimination de code « mort » ou inatteignable
Élimine le code qui ne sera jamais exécuté, tel que
debug = 0;
if (debug)
x = x + t;
Systèmes ordinés en temps réel
40
20
Techniques d’optimisation utilisées par les compilateurs
— Propagation de constantes
Certaines assignations à des variables peuvent être remplacées par des
constantes, tel que
x = 100;
y = x;
x = 100;
y = 100;
— Élimination de stockage « mort » ou inutile
Certaines variables utilisées pour du stockage temporaire peuvent être
éliminées, tel que
t = y + z;
x = sin(y+z);
x = sin(t);
— Élimination de variables « mortes »
Élimine les variables qui semblent inutiles, tel que
x = y + z;
x = y;
x = y;
Systèmes ordinés en temps réel
41
Techniques d’optimisation utilisées par les compilateurs
— Équations logiques court-circuitées
Transforme une équation logique compliquée en une série de
sous-expressions qui seront évalué une à la fois, tel que
if (x > 0)
if (y > 0)
z = 1;
if (x > 0) && (y > 0)
z = 1;
— Déroulement de boucle
Déroule les boucles courtes, tel que
for (i = 0; i < 3; i++)
a[i] = 7*b[i+2];
a[0] = 7*b[2];
a[1] = 7*b[3];
a[2] = 7*b[4];
Systèmes ordinés en temps réel
42
21
Optimisation du code
Systèmes ordinés en temps réel
43
Trucs et conseils pour optimiser le code C
—Limites et mise en garde
• Les langages de haut niveau offrent plus ou moins
de contrôle sur les instructions générées;
• Les options du compilateur (en particulier, le
niveau d’optimisation) ont un impact prépondérant
sur la performance;
• Rien ne peut remplacer la sélection d’algorithmes
performants.
Systèmes ordinés en temps réel
44
22
Truc 1 – Réduire l’utilisation de la pile
—Réduire les paramètres et les variables locales.
—Réduire le nombre de fonctions.
• Compromis entre performance et clarté du code.
—Simuler les fonctions
• Il est possible de «simuler ou mimer» les fonctions
avec les directives de pré-compilation.
Ex. : #define poly2( a , b, c , x) \
( (a)*(x)*(x)+ (b)*(x)+(c) )
Systèmes ordinés en temps réel
45
Truc 2 - Pas d’allocation dynamique
—Ne pas utiliser l’allocation de mémoire
dynamique.
• L’allocation de mémoire fait appel au système
d’exploitation pour obtenir une portion de la
mémoire disponible;
• C’est un processus lent.
Solution :
• Allocation statique, ou;
• Allocation dynamique SEULEMENT durant
l’initialisation.
Systèmes ordinés en temps réel
46
23
Truc 3 – Variables de type register
— Déclarer les variables très utilisées (ex. : les
compteurs) comme registres.
• Mode d'allocation Æ register.
— Il n’est pas sous garantie que le processeur
utilisera un registre, mais c’est souvent le cas.
Systèmes ordinés en temps réel
47
Truc 4 – Rendre les conversions explicites
— Le langage C se convertit toujours au type qui
exige le plus de ressources avant de faire des
opérations.
• Exemple :
double multiplicateur = 2.0;
int x, n;
x = ((int) multiplicateur) * n;
Comme x et n sont de type int, on évite que l'opération
soit effectuée en double.
Systèmes ordinés en temps réel
48
24
Truc 5 – Réduire la complexité mathématique
— L'objectif est d'utiliser des instructions plus simples
pour faire les mêmes calculs (pyramide des instructions).
Logiques
Bit shift
Branchements
Plus rapide
ADD CMP SUB
Multiplication
Division
Exemple :
— * 2n
Remplacer par un décalage
à gauche de n bits;
— Division par x
* 1/x si x ne change pas
ou si votre CPU offre une
instruction INVERSION
plus performante.
Racine carrée
Systèmes ordinés en temps réel
49
Truc 6 – Éliminer les appels au OS ou au BIOS
— Les appels au système d'exploitation (ou au BIOS)
peuvent être plus lents parce que :
• Le système effectue des opérations / vérifications afin de
protéger le système.
˜ Validation des arguments;
˜ Vérification des erreurs.
• Implique généralement une interruption logicielle;
• Lors des appels au système, celui-ci en profite souvent pour
faire des mises à jour internes ("housekeeping") – Exemple :
mise à jour de l'horloge.
— Deux problèmes :
• Solution est beaucoup moins portable;
• Votre code doit être optimisé – plus vite que celui du OS.
Systèmes ordinés en temps réel
50
25
Truc 7 – Ordre dans l'accès au tableau
— En langage C, les éléments des tableaux sont
emmagasinés "par colonnes« .
table[5][3]
— Dans une boucle, optimiser l'accès en
"bouclant" d'abord sur le dernier index.
—Exemple :
int somme = 0;
for (i=0; i<5;i++)
for (j=0;j<3;j++)
somme +=
table[i][j];
Systèmes ordinés en temps réel
51
Truc 8 – Réduire et simplifier les équations
— On a avantage à éliminer la répétition de
calculs
— Factorisation
xp[i] = cos(theta) * x[i] + sin(theta) * y [i];
yp[i] = - sin(theta) * x[i] + cos(theta) * y [i];
c_theta = cos(theta);
s_theta = sin(theta);
xp[i] = c_theta* x [i] + s_theta * y [i];
— Éliminer les opérations inutiles
Æ*0 , *1 , +0 , -0
Æa=b
x = sqrt ( a2 – b2)
Systèmes ordinés en temps réel
52
26
Truc 9 – Pré-calcul des constantes
—Exemple :
• w = 2 * PI * frequence;
• #define 2PI
6.28301
• w = 2PI *frequence;
Systèmes ordinés en temps réel
53
Truc 10 – Simplifier les boucles
—Éliminer les expressions constantes ou
communes dans les boucles.
Exemple :
for (i=0; i < 100 ; i++)
x[i] = x [i] + 2*w*t;
devient
z = 2*w * t;
for (i=0; i < 100 ; i++)
x[i] = x [i] + z;
// on sauve 198 multiplications
Systèmes ordinés en temps réel
54
27
Truc 11 – Dérouler les petites boucles
— Dans les petites boucles, on accepte
d'augmenter la taille du programme pour
éliminer les tests.
for (i=1; i < 4 ; i++)
x[i] = x [i] + 1;
devient
x[1] = x [1] + 1;
x[2] = x [2] + 1;
x[3] = x [3] + 1;
— On sauve 9 instructions car le "for" est en fait Æ
Systèmes ordinés en temps réel
INC
TEST
(…..)
JMP
55
Truc 12 – Combiner les boucles
— Il faut regrouper les boucles :
for (i=0; i < 100 ; i++)
x[i] = y [i] * 8;
for (i=0; i < 100 ; i++)
z[i] = x [i] * y[i];
devient
for (i=0; i < 100 ; i++)
{
x[i] = y [i] * 8;
z[i] = x [i] * y[i];
}
— On sauve 300 instructions car le "for" est en fait Æ
Systèmes ordinés en temps réel
INC
TEST
(…..)
JMP
56
28
Truc 13 – Choisir un type de variable plus simple
— Lorsqu'on utilise que "certaines propriétés" d'un type
on peut essayer de prendre un type plus simple.
— Exemple : Simuler les variables réelles (float) par une
variable entière multipliée par la précision voulue
Si la précision sur un calcul est limitée (ex.: par le
capteur), alors nous pouvons utiliser des entiers.
1382
138.2
Plus rapide de faire les
calculs avec des
opérations entières
int
Float
36
3.6
Systèmes ordinés en temps réel
57
Truc 14 – Table de correspondance
— Si vous utilisez souvent une fonction mathématique
complexe, il peut être avantageux d'échantillonner la
fonction et de calculer ses valeurs par interpolation.
Exemple :
sin (x) = x – x3/3! + x5/5! – x7/7! + x9/9! - …
x
0
1
2
3
sin(x)
0
…
…
…
…
Note :
— Possible de perdre de la précision sur la valeur obtenue.
— Taille du tableau augmente rapidement avec le nombre
de variables.
Systèmes ordinés en temps réel
58
29
(Truc 15) – Écrire le code en assembleur
— En principe, il est possible d'écrire le code en
assembleur afin d'obtenir la meilleure
performance possible.
—En pratique,
—Difficile (coûteux) de produire du code assembleur;
—Difficile (coûteux) de produire du code "plus
optimisé" que les compilateurs;
—Difficile à maintenir et non portable.
—En pratique, on optimise que des petites
portions très critiques du code.
• Pas en examen
Systèmes ordinés en temps réel
59
Mesure de performance
Systèmes ordinés en temps réel
60
30
3.9 Mesure de la performance
Objectif : Améliorer l’exécution des portions
critiques de notre code en langage C.
—Mesure : Chronométrage des fonctions
• Nous allons voir 3 façons d’estimer le temps
d’exécution d’une section de code :
˜Mesure directe
• Boucle sur plusieurs itérations;
• Chronométrage de haute précision.
˜Décompte d’instructions
˜Décompte des entrées / sorties
—Trucs possibles
Systèmes ordinés en temps réel
61
3.9 Mesure directe de la performance
—Mesure du temps d’exécution dans une boucle
mesure_du_temps_avant; // ex: gettime() ou clock()
for (i=0, i < Nb_itération ; i++)
ma_fonction ( );
mesure_du_temps_après;
—Avantages :
• Pas besoin d’une mesure très précise de l’horloge;
• Moyenne sur les plusieurs exécutions.
—Inconvénients :
• Attention à l’impact du compilateur (i.e. optimisation);
• Vérifier la linéarité pour Nb_itération assez grand.
Systèmes ordinés en temps réel
62
31
3.9 Mesure du temps – Horloge vs minuterie
— Deux concepts interreliés
— Horloge (« Clock »)
• Fournie un mesure du temps
• Définition :
˜ 1 seconde = 1/86 400 de la journée solaire moyenne;
˜ 1 seconde = 1/31 566 925.9747 année 1900 au tropique;
˜ 1 seconde = 9 192 631 770 vibration Cesium133.
• Mesure du temps ↔ intervalle entre deux évènements.
— Minuterie (« Timer »)
• Génère un événement après un intervalle de temps spécifié.
Systèmes ordinés en temps réel
63
3.9 ANSI C – Fonction date & time
Æ time_t time( time_t *timer ); // timer.h
Get current system time as type time_t
Résultat :
struct tm {
int tm_sec; /* seconds after the minute - [0,59] */
int tm_min;
/* minutes after the hour - [0,59] */
int tm_hour;
/* hours since midnight - [0,23] */
int tm_mday;
/* day of the month - [1,31] */
int tm_mon;
/* months since January - [0,11] */
int tm_year;
/* years since 1900 */
int tm_wday;
/* days since Sunday - [0,6] */
int tm_yday;
/* days since January 1 - [0,365] */
int tm_isdst;
/* daylight savings time flag */
};
— Résolution : ± 1 seconde
Systèmes ordinés en temps réel
64
32
3.9 ANSI C – Fonction clock
Æ clock_t clock( void );
Retourne le nombre de ticks de l’horloge
Notes :
•
•
•
•
typedef long clock_t;
Temps en secondes = clock_t/CLOCKS_PER_SEC;
Sous Windows2000, CLOCKS_PER_SEC = 1 000;
Sous DOS (TurboC), CLOCKS_PER_SEC = 18.2.
— Résolution : ± 1 milliseconde
Systèmes ordinés en temps réel
65
3.9 Test – Clock on Windows2000
— Programme de test :
start = clock();
Sleep (1);
// sleep time in milliseconds
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
— Résultat :
• (finish - start) = 15
et duration = 0.015 s
• Avec Sleep(0) ou sans Sleep();
• (finish - start) =
0
et duration = 0
Systèmes ordinés en temps réel
66
33
3.9 Mesure du temps – INTEL
— Mesure du temps d’exécution avec instruction
RDTSC : read time-stamp counter
Registre de 64 bit incrémenté à chaque cycle du CPU
RDTSC Æ 32 bits dans EDX et 32 bits dans EAX
— Avantages :
• Permet une mesure de sections très petites.
— Inconvénients :
• Disponible seulement sur les processeurs Pentiums;
• Besoin de « sérialiser » l’exécution;
˜ Pentium support l’exécution hors ordre (out-of-order);
˜ Les instructions en assembleur ne sont pas nécessairement
exécutées dans l’ordre où elles apparaissent dans le code;
• Attention à l’impact du compilateur (ex. : optimisation); Chrono.pdf
• Vérifier la linéarité.
Systèmes ordinés en temps réel
Ref: http://www.intel.com/drg/pentiumII/appnotes/rdtscpm1.pdf
67
3.9 Mesure directe de la performance – INTEL
— Exemple :
(Mode DEBUG Æ Pas d’optimisation)
float z,q,x,y,result;
result=0.0f; x=2.0f; y=100.0f; z=12.0f; q=5.0f;
// CODE DANS LA BOUCLE de mesure du temps d'execution
z += y;
q *= x;
result = z/q;
— Moyenne (5 itérations)
Average cycles per loop :
Average cycles per loop :
Average seconds per loop:
782.000000 (incluant la mesure)
257.000000 (excluant la mesure)
0.000000129 secondes
— Moyenne (5 000 itérations)
Average cycles per loop :
Average cycles per loop :
Average seconds per loop:
2599.000000 (incluant la mesure)
2074.000000 (excluant la mesure)
0.000001037 secondes
Pourquoi ?
Systèmes ordinés en temps réel
68
34
3.9 Mesure directe de la performance – INTEL
— Exemple :
(Mode DEBUG Æ Pas d’optimisation)
float z,q,x,y,result;
result=0.0f; x=2.0f; y=100.0f; z=12.0f; q=5.0f;
// CODE DANS LA BOUCLE de mesure du temps d'execution
x=2.0f; y=100.0f; z=12.0f; q=5.0f;
z += y;
q *= x;
result = z/q;
Temps d’éxécution dépend des données
— Moyenne (5 itérations)
Average cycles per loop :
Average cycles per loop :
Average seconds per loop:
777.000000 (incluant la mesure)
252.000000 (excluant la mesure)
0.000000126 secondes
— Moyenne (5 000 itérations)
Average cycles per loop :
Average cycles per loop :
Average seconds per loop:
607.000000 (incluant la mesure)
82.000000 (excluant la mesure)
0.000000041 secondes
Optimisation sur plusieurs itérations ?
Systèmes ordinés en temps réel
69
3.9 Mesure directe de la performance – INTEL
— Exemple :
(Mode RELEASE Æ optimisation temps d’exécution)
float z,q,x,y,result;
result=0.0f; x=2.0f; y=100.0f; z=12.0f; q=5.0f;
// CODE DANS LA BOUCLE de mesure du temps d'execution
x=2.0f; y=100.0f; z=12.0f; q=5.0f;
z += y;
q *= x;
result = z/q;
— Moyenne (5 itérations)
Average cycles per loop :
Average cycles per loop :
Average seconds per loop:
536.000000 (incluant la mesure)
32.000000 (excluant la mesure)
0.000000016 secondes
— Moyenne (5 000 itérations)
Average cycles per loop :
Average cycles per loop :
Average seconds per loop:
570.000000 (incluant la mesure)
66.000000 (excluant la mesure)
0.000000033 secondes
Compilation
Systèmes ordinés en temps réel
AVR
70
35
3.9 Décompte des instructions
— Analyse du code assembleur
• Évaluation du temps d’exécution de chaque instruction.
— Difficultés et limites
• Pas facile / impossible d’estimer le temps d’exécution d’une
séquence d’instructions sur les architectures complexes;
• Souvent le temps d’exécution varie;
• Travail laborieux .
Exemple : Entrée / sortie par interrogation
BYTE8 Serial_Input(void)
{
/* Attendre l’arrivée d’une nouvelle donnée */
while ((inportb(STATUS_PORT) & READY) == 0) {}
return inportb(DATA_PORT) ;
}
void Serial_Output(BYTE8 ch)
{
/* Attendre que le périphérique soit prêt */
while ((inportb(STATUS_PORT) & READY) == 0){}
outportb(DATA_PORT, ch) ;
}
Réf. : Lewis, Chap. 6
Systèmes ordinés en temps réel
71
3.9 Décompte des instructions
_Serial_Input:
SI1:
MOV
DX,02FDh
; DX Å Status Port Address
IN
AL,DX
; Read Input Status Port
TEST
AL,00000001B
; Check the “Ready” Bit
JZ
SI1
; Continue to wait if not ready
MOV
DX,02F8h
; Else load DX with Data Port Address
XOR
EAX,EAX
; Pre-clear most significant bits of EAX
IN
AL,DX
; Read Data Port
RET
Réf: Lewis Chap 6.
; return to caller with data in EAX
Systèmes ordinés en temps réel
72
36
3.9 Décompte des entrées / sorties
—Modèle approximatif basé sur l’observation
que la performance est souvent limitée par le
temps nécessaire aux accès mémoire.
—On doit inclure :
• La lecture des instruction;
• Les accès aux registres des périphériques.
—On néglige :
• Les facteurs d’accélération dus à la mémoire cache,
à la présence d’un pipeline et de plusieurs ALU;
• L’estimation est donc pessimiste.
ET TRÈS IMPRÉCISE
Systèmes ordinés en temps réel
Réf: Lewis Chap 6.
73
3.9 Décompte des entrées / sorties
_Serial_Input:
MOV
SI1:
IN
TEST
JZ
MOV
XOR
IN
RET
DX,02FDh
AL,DX
AL,00000001B
SI1
DX,02F8h
EAX,EAX
AL,DX
;
;
;
;
;
;
;
;
;
;
Opcode
Bytes
1
1
1
1
1
1
1
1
Immediate Stack
Bytes
Bytes
2
I/O
Transfers
1
1
1
2
4
1
14 octets pour les instructions ,
4 octets pour la pile ,
2 octets pour les entrées / sorties
Réf. : Lewis, Chap. 6
Systèmes ordinés en temps réel
74
37
3.9 Décompte des entrées / sorties
— Exemple : Architecture considérée
(Æ c.f. lewis)
• Accès en mémoire
Æ 60 ns;
• Bus PCI 33 MHz
Æ 30 ns par accès.
En général, les transferts demandent plusieurs
cycles d’accès.
Décompte:
(14 octets / (4 octets par cycle)) * 60 ns = 240 ns (instructions)
(4 octets / (4 octets par cycle)) * 60 ns = 60 ns (pile)
2 octets * 30 ns
= 60 ns (Entrée / sortie)
Total
= 360 ns
Taux de transfert maximum = 1/360 ns = 2.78 Moctets/s
Réf. : Lewis, Chap. 6
Systèmes ordinés en temps réel
75
3.9 Décompte des entrées / sorties
—Autre exemple : Entrées / sorties par interruption
—Temps de réponse :
R = Li + Cs + LIRQV + Ai + Cr
— Li = temps de la plus longue instruction
•
•
•
•
PUSHA Æ sauvegarde des registres
1 cycle d’accès mémoire pour l’instruction
8 cycles d’accès mémoire pour écrire les 8 registres
9 * 60 ns = 540 ns
— LIRQV = temps de traitement de l’interruption (niveau matériel)
•
•
•
•
12 octets sur la pile (3 cycles)
1 octet E/S (lecture du vecteur)
16 octets pour chargement PC (4 cycles)
Total
Réf. : Lewis, Chap. 6
Systèmes ordinés en temps réel
Æ 180 ns
Æ 30 ns
Æ 240 ns
= 450 ns
76
38
3.9 Interruptions – Intel x86 (mode protégé)
Réponse aux interruptions
Action
Bytes
Transferred
Detailed description
1. Push EFlags
register.
ESP ← ESP - 4;
MEM32[ESP] ← EFlags
4 (stack write)
2. Disable
interrupts.
IF Flag ← 0 (Also clears TF Flag)
n/a
3. Push CS
ESP ← ESP - 4; MEM32 [ESP] ← CS
4 (stack write)
3. Push EIP
ESP ← ESP - 4; MEM32 [ESP] ← EIP
4 (stack write)
4. Identify
interrupt.
Read interrupt type code from data bus.
1 (I/O read)
5. Load CS and EIP
CSvisible,EIP ← IDT64[8 × int. type code]
CShidden Å GDT64[CSvisible]
8 (IDT read) +
8 (GDT read)
Réf. : Lewis, Chap. 6
Systèmes ordinés en temps réel
77
3.9 Décompte des entrées / sorties
Instr. Data
Bytes Bytes
_Serial_Input_ISR:
STI
PUSH
PUSH
MOV
IN
MOV
MOV
OUT
POP
POP
IRET
; Enable high prior. Ints. 1
EAX
; Preserve contents
1
EDX
; of EAX and EDX.
1
DX,02FDh
; Retrieve the data and 3
AL,DX
; clear the request.
1
[_serial_data],AL ; Save the data away.
5
AL,00100000b
; Send EOI command to 2
20h,AL
; Prog. Interrupt Ctlr.
2
EDX
; Restore orig. contents 1
EAX
; of the registers.
1
; Restore EIP and EFlags. 1
Stack
Bytes
I/O
Transfers
4
4
1
1
4
4
12
1
19 octets pour les instructions ,
1 octet pour la donnée
28 octets pour la pile ,
2 octets pour les entrées / sorties
Réf. : Lewis, Chap. 6
Systèmes ordinés en temps réel
78
39
3.9 Décompte des entrées / sorties
Décompte :
(19 octets / (4 octets par cycle)) * 60 ns = 300 ns (instructions)
(28 octets / (4 octets par cycle)) * 60 ns = 420 ns (pile)
( 1 octet / (4 octets par cycle)) * 60 ns = 60 ns (donnée)
2 octets * 30 ns
= 60 ns (Entrées / sorties)
Total
= 840 ns
Taux de transfert maximum = 1/1.95 µs = 0.513 Moctets/s
Finir l’instruction
PUSHA: 0.54 µs
Réponse
matérielle
Temps d’exécution
0.45 µs
0.84 µs
Total = 1.95 µs
Réf: Lewis Chap 6.
Systèmes ordinés en temps réel
79
40
Téléchargement