> J'ai fait un jour l'expérience suivante : J'ai écrit un programme (en 
> asembleur) allant lire le registre des clock tick sur un CPU. Puis, dans mon 
> programme C appelant la fonction, j'ai essayé de déterminer l'overhead de cet 
> appel, afin de le soustraire de mes calculs lorsque je voulais mesurer une 
> courte période de temps. A ma grande surprise, en collectant les valeurs, 
> j'ai obtenu de grandes variations  dans mes mesures. Donc, à un moment on est 
> confronté au choix d'utiliser la valeur minimum, ou une valeur moyenne... 
> C'est ce jour là que j'ai véritablement saisi l'impact que les autres process 
> peuvent avoir sur un code même très court. Et encore... je ne faisais pas 
> appel à des valeurs en mémoires (caches), ni de stresse du BHT...

Ceci mesure surtout l'effet de l'OS et des différentes tâches qui tournent ou 
ne tournent pas à un moment donné. Même si les registres de caches de saut 
n'existaient pas, la variation resterait (probablement amplifiée par la perte 
de performance).

> Maintenant... on peut aborder ce que tu dis :
> 
> permet d’exécuter 3 instructions en parallèle par cycle au maximum.
> 
> 
> C'est justement dans le mot permet que ça devient intéressant. Donc, selon 
> cette théorie, on devrait avoir un CPI de 0.33...

Un CPI minimum théorique de 0.33, c'est exact. Si je reprends mon exemple avec 
le Cortex-M15, un pipeline sans prédiction de branchement, qui ne fait donc 
rien entre 70% et 87% de son temps, on obtient un CPI compris entre: 3.33 et 
5.88.

> Je me trompe où on en est loin ? Je n'ai pas de valeur pour l'ARM, mais les 
> dernières valeurs que j'ai vu passées sont supérieures à 1. Bien que le CPI 
> ne dise pas tout, c'est une indication. De plus, 3 instructions... mais 
> lesquelles ? Tout ceci est fantastique si toutes les instructions ne 
> s'exécute qu'en un seul cycle. Or, beaucoup d'instructions nécessitent bien 
> plus de cycle. Certains mode d'adressage sont d'ailleurs des tueurs dans ce 
> domaine, de même que les opérations de calcul, dont la division est un gros 
> point noir. Alors, que ce passe-t-il dans ce cas dans le CPU ? Le CPU est-il 
> en attente de la fin de toutes les instructions, ou est-il capable de shifter 
> une partie des instructions dans le pipe (j'en doute). Qui plus est, si une 
> instruction fait appel à une valeur qui ne se trouve pas dans la cache L1 ? 
> Là le processeur est en "stall"...

Bien sûr, on peut toujours chercher les pires des cas, mais c'est comme pour 
les benchmarks que vous ne trouviez pas réalistes. Il faut regarder la moyenne 
sur un ensemble représentatif. Au moins les benchmarks sont une liste de 
plusieurs programmes différents.

> Les techniques que tu décris pour l'ARM ne sont pas nouvelles, car elles sont 
> toutes issues de ce qui a été introduit avec les processeurs RISC dans les 
> années 80. C'est aussi là que l'on s'est rendu compte qu'il y a loin de la 
> théorie à la pratique. Les techniques d'optimisation ont permit de minimiser 
> l'impact des pipe-flush, sans arriver à les éliminer complètement.

Le processeur Alpha 21064 introduit les pipelines longs (super pipeline) en 
1992. MIPS et Sparc ont introduits les premiers processeurs RISC à pipeline 
court dans le domaine commercial quelques années avant. Le superscalaire, 
l'exécution dans le désordre et la spéculation de branchement n'apparaissent 
que dans le courant des années 90. Si j'ai raté quelque chose, je veux bien que 
vous m'en donniez quelques exemples.

> La théorie et les hypothèses c'est bien et passionnant, mais c'est lorsque 
> l'on fait véritablement des mesures que l'on se rend compte que certaines 
> choses ne sont pas ce que l'on croit.

Je suis bien d'accord. Je vous propose de faire une démonstration en prenant 
SimpleScalar (http://www.simplescalar.com/) qui est un simulateur de processeur 
RISC superscalaire avec exécution dans le désordre. Cous pouvez paramétrer tous 
les composants de l'architecture et passer toutes les caches à une taille de 0. 
Ensuite, vous prenez les programmes C qui composeront votre benchmark et vous 
les compilez pour l'architecture choisie avant de lancer le simulateur qui vous 
donne une exécution instrumentée de votre code. Vous reprenez ensuite avec des 
caches de taille classiques et vous faites la différence.

Au plaisir de lire vos résultats.


Dominik



_______________________________________________
gull mailing list
[email protected]
http://forum.linux-gull.ch/mailman/listinfo/gull

Répondre à