[gull] Above Meltdown & Spectre
Daniel Cordey
dc at pxcluster.com
Thu Feb 8 12:11:16 CET 2018
On 08. 02. 18 07:05, Dominik Madon wrote:
>
> Le pipeline du Cortex-M15 de l’ARM, par exemple, compte 15 étages et permet d’exécuter 3 instructions en parallèle par cycle au maximum. Il peut en théorie traiter simultanément jusqu’à 59 instructions à différentes étapes de leur exécution. Voici un morceau de code que je viens d’extraire d’un de mes programmes en ligne de commande que j’utilise régulièrement (ce n’est _pas_ du benchmark):
Merci pour cette analyse très détaillée et intéressante. C'est justement
la taille du BHT qui est intéressante. Tout ceci est très efficace pour
des pattern que l'on retrouve justement dans des programmes de calcul
intensif. Ce qui fait que ces techniques sont très utiles lorsque l'on
fait des boucles, mais a un impact beaucoup plus limité sur des
branchements "one shot". L'impact est alors de 50% inférieur à la
situation idéale et se trouve noyé dans le reste; ce qui fait qu'à un
certain point on ne peux plus "mesurer" l'impact.
On fait des hypothèse sur la base de l'examen du code source. C'est bien
mais ça fonctionne rarement comme ça, hélas. Le BHT est utilisé pour
d'autres process, de même que les caches (L1 à L3). On peut bien sûr se
mettre dans une situation qui va minimiser l'impact des autres process,
mais nous sommes sur des machines avec des process systemes qui tournent
quoi que l'on fasse. En enlevant un max de process on se remet dans une
situation de toy benchmark qui nous permet d'obtenir des valeurs que
personne n'arrivera à reproduire en situation réelle.
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...
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...
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"...
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.
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.
dc
More information about the gull
mailing list