Il y a
quelque temps j’avais essayé de porter le programme 32 bits qui indiquait le
nombre d’instructions et de cycles d’une routine en assembleur 64 bits. Je n’y
étais pas arrivé car l’appel système PERF_EVENT_OPEN n’était pas disponible en
64 bits. J’avais donc essayé de lire les valeurs directement du registre compteur
de cycles proposé par le processeur Cortex A53 mais hélas les instructions de type
msr ou mrs sont refusées lors de l’exécution d’un programme exécuté avec la
version raspbian buster. Je n’ai pas trouvé pourquoi !!
Mais je me
suis repenché sur le problème et maintenant le fonctionnement de PERF_EVENT_OPEN
est correct en 64 bits. Est-ce la nouvelle version de Buster ? la mise à
jour du package linux-perf ? ou la mise en place des packages suivants nécessaires
pour la création de modules du kernel :
sudo apt
install build-essential fakeroot dpkg-dev perl libssl-dev bc gnupg dirmngr
libncurses5-dev libelf-dev flex bison
je l’ignore
mais maintenant il est possible d’extraire le nombre d’instructions, le nombre
de cycles et le temps pris par des instructions ou une routine.
Je vous
conseille de vous plonger dans la documentation (en anglais) de l’appel système
linux PERF_EVENT_OPEN car les possibilités sont nombreuses.
Ici je vais
utiliser la possibilité de regrouper les 3 mesures dans le même buffer en
créant un process leader et 2 process fils. Cette solution permet de lancer en
une seule commande la mesure et d’arrêter la mesure grâce à l’identifiant du
leader seul. Les commandes utilisent l’appel système IOCTL puis l’appel READ
pour lire les résultats.
Les tests du
programme mesurePerf1.s montrent que les
résultats sont surprenants. Le comptage des instructions doit tenir compte de toutes
les instructions comprises entre les 2 svc de lancement et d’arrêt de la
mesure.
Pour les
cycles, les résultats sont très variables si on se contente d’une seule mesure.
J’ai donc mis une boucle de mille mesures ce qui permet d’avoir une meilleure
estimation du nombre de cycles.
Par exemple
pour le simple test du mov x0,1, le nombre d’instruction est de 3012, ce qui
correspond à 1001 fois les 3 instructions mov, subs et cbnz et les 9 autres
instructions comprises entre les 2 svc (et en les comptant).
Pour le
nombre de cycles , celui est variable autour de 2080 ce qui semble indiquer que
les 3003 instructions de la boucle correspondent à 2000 cycles.
Or je m’attendais
à avoir un nombre de cycles supérieur au nombre d’instructions !! Ce n’est
pas le cas et la recherche du fonctionnement de ce type de processeur me fait
penser que l’on voit là le gain des architectures pipe line de traitement des
instructions.
Si on ajoute
une instruction mul, le nombre de cycles augmente seulement de mille alors que
cette instruction est donnée pour utiliser au minimum 2 cycles.
En ce qui
concerne les temps, ils sont très très variables !!! Donc la recherche d’optimisation
ne va être très facile sauf à faire tourner les routines des millions de fois
pour voir l’évolution d’une modification.
Mais ce n’est
que le début et je vais poursuivre des tests en particulier sur la routine de
division de nombres de 128 bits utilisée dans le chapitre précédent.
Bonjour :-) Super job!
RépondreSupprimerJ’ai des problèmes d’accès au chapitre 4, 12 et 14.
Mon compte google n’est pas autorisé :-p
Bonsoir.
RépondreSupprimerJ'ai republié ces chapitres ainsi que le chapitre 87 pour essayer de résoudre ces problèmes car je n'ai rien changé dans blogger pour ces chapitres particuliers.
Merci et bon courage.