This is an old revision of the document!
Opération | Heure (ns) | Notes |
---|---|---|
Référence de cache L1 | 0,5 ns | |
Prédiction de branche | 5 ns | |
Référence de cache L2 | 7 ns | 14x cache L1 |
Verrouillage / déverrouillage mutex | 25 ns | |
Référence de la mémoire principale | 100 ns | Cache 20x L2, cache 200x L1 |
Compresser 1K octets avec Zippy | 3000 ns | |
Envoyer 1K octets sur un réseau de 1 Gbps | 10 000 ns | 0,01 ms |
Lire 4K au hasard à partir du SSD * | 150 000 ns | 0,15 ms |
Lecture séquentielle de 1 Mo de la mémoire | 250 000 ns | 0,25 ms |
Aller-retour dans le même centre de données | 500 000 ns | 0,5 ms |
Lire 1 Mo séquentiellement à partir du SSD * | 1.000.000 ns | 1 ms, 4x mémoire |
Recherche de disque | 10.000.000 ns | 10 ms, 20 fois le centre de données aller-retour |
Lecture séquentielle de 1 Mo sur le disque | 20 000 000 ns | 20 ms, 80x mémoire, 20x SSD |
Envoyer un paquet Caracal - NY - Caracal | 150 000 000 ns | 150 ms |
Un profileur est un outil d'analyse des performances qui aide le programmeur à déterminer les points critiques de goulot d'étranglement d'un programme. Ceci est fait en examinant le comportement du programme, en évaluant la consommation de mémoire et la relation entre ses modules. Le titulaire du profil est disponible à l'adresse suivante: * bibliothèque C ++ (GNU libc), grâce aux informations sur la durée de vie de la mémoire,
Les deux manières de profiler sont les suivantes:
Les profils basés sur cette technique nécessitent généralement changements dans le code du programme: insérez des sections de code au début et à la fin de la fonction que vous souhaitez analyser. De plus, les fonctions appelées sont conservées. Ainsi, il est possible d'estimer le temps total de l'appel lui-même et des appels de la sous-fonction. L’inconvénient majeur de ces profils est lié à la modification du code: dans les fonctions d’appel faibles et souvent appelées, cette surcharge peut entraîner une mauvaise interprétation des résultats.
Les profileurs basés sur l'échantillonnage ne changent pas dans le code du programme, mais vérifient périodiquement le processeur pour déterminer quelle fonction (instruction) est en cours d'exécution. Ensuite, il estime la fréquence et le temps d'exécution d'une fonction particulière sur une période donnée.
Vous trouverez ci-dessous quelques outils utilisés pour le profilage. ==== ==== PerfCounters La plupart des processeurs modernes offrent des “compteurs de performance” qui comptent différents types d’événements matériels: instructions exécutées, erreurs de cache, instructions manquées ou manquées, sans affecter les performances du noyau ou des applications. Ces registres peuvent déclencher des interruptions lorsqu'un certain nombre d'événements s'accumulent et peuvent donc être utilisés pour analyser le code exécuté sur le processeur en question.
La sous-catégorie perfcounters
:
CONFIG_PERF_COUNTERS = y
) oprofile
événements matériels
(instructions, accès en cache, cycles de bus). événements logiciels
(erreur de page, cpu-clock, migrations de cpu). tracespoints
(par exemple, sys_enter_open, sys_exit_open).L'utilitaire 'perf' est l'interface du sous-système 'perfcounters' avec l'utilisateur. Il fournit une ligne de commande similaire à “git” et ne nécessite pas l'existence d'un démon.
Un tutoriel sur la performance que vous trouverez aici.
$ perf [--version] [--help] COMMAND [ARGS]
Les commandes
les plus utilisées sont:
annotate
- Lisez perf.data
et affichez le code avec des annotations list
- Liste les noms symboliques de tous les types d'événements pouvant être suivis par perf
verrouiller
- Analyse les événements de verrouillage record
- Exécute une commande et enregistre les informations de profilage dans le fichier perf.data report
- Lit perf.data (créé par perf record) et affiche le profil state
- Exécute une commande et affiche les statistiques postées par le sous-système des compteurs de performance top
- Génère et affiche des informations en temps réel sur le téléchargement d'un système
Affiche les noms symboliques de tous les types d'événements pouvant être suivis par perf
.
$ perf list List of pre-defined events (to be used in -e): cpu-cycles OR cycles [Hardware event] instructions [Hardware event] cpu-clock [Software event] page-faults OR faults [Software event] L1-dcache-loads [Hardware cache event] L1-dcache-load-misses [Hardware cache event] rNNN [Raw hardware event descriptor] mem:<addr>[:access] [Hardware breakpoint] syscalls:sys_enter_accept [Tracepoint event] syscalls:sys_exit_accept
Lorsqu'un événement n'est pas disponible sous forme symbolique, il peut être utilisé avec perf sous la forme du processeur dans le système en cours d'analyse.
perf-état Exécutez une commande et affichez les statistiques publiées par le sous-système des compteurs de performance.
$ perf stat ls -R /usr/src/linux Performance counter stats for 'ls -R /usr/src/linux': 934.512846 task-clock-msecs # 0.114 CPUs 1695 context-switches # 0.002 M/sec 163 CPU-migrations # 0.000 M/sec 306 page-faults # 0.000 M/sec 725144010 cycles # 775.959 M/sec 419392509 instructions # 0.578 IPC 80242637 branches # 85.866 M/sec 5680112 branch-misses # 7.079 % 174667968 cache-references # 186.908 M/sec 4178882 cache-misses # 4.472 M/sec 8.199187316 seconds time elapsed
“perf stat” offre la possibilité de collecter des données en exécutant plusieurs fois un programme en spécifiant l'option ”-r”.
$ perf stat -r 6 sleep 1 Performance counter stats for 'sleep 1' (6 runs): 1.757147 task-clock-msecs # 0.002 CPUs ( +- 3.000% ) 1 context-switches # 0.001 M/sec ( +- 14.286% ) 0 CPU-migrations # 0.000 M/sec ( +- 100.000% ) 144 page-faults # 0.082 M/sec ( +- 0.147% ) 1373254 cycles # 781.525 M/sec ( +- 2.856% ) 588831 instructions # 0.429 IPC ( +- 0.667% ) 106846 branches # 60.806 M/sec ( +- 0.324% ) 11312 branch-misses # 10.587 % ( +- 0.851% ) 1.002619407 seconds time elapsed ( +- 0.012% )
Notez les événements les plus importants énumérés ci-dessus.
man perf-top Génère et affiche des informations en temps réel sur le téléchargement d'un système.
$ ls -R /home $ perf top -p $(pidof ls) -------------------------------------------------------------- PerfTop: 181 irqs/sec kernel:72.4% (target_pid: 10421) -------------------------------------------------------------- samples pcnt function DSO _______ _____ ____________________ ___________________ 270.00 15.8% __d_lookup [kernel.kallsyms] 145.00 8.5% __GI___strcoll_l /lib/libc-2.12.1.so 99.00 5.8% link_path_walk [kernel.kallsyms] 97.00 5.7% find_inode_fast [kernel.kallsyms] 91.00 5.3% __GI_strncmp /lib/libc-2.12.1.so 55.00 3.2% move_freepages_block [kernel.kallsyms] 44.00 2.6% ext3_dx_find_entry [kernel.kallsyms] 41.00 2.4% ext3_find_entry [kernel.kallsyms] 40.00 2.3% dput [kernel.kallsyms] 39.00 2.3% ext3_check_dir_entry [kernel.kallsyms]
Nous notons que les fonctions de gestion de fichiers (défilement, recherche) sont celles qui apparaissent le plus souvent dans la sortie parfaite de la commande de liste récursive du répertoire de base.
record homme
Exécute une commande et enregistre les informations de profilage dans le fichier perf.data
.
$ perf record wget http://elf.cs.pub.ro/so/wiki/laboratoare/laborator-07 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.008 MB perf.data (~334 samples) ] $ ls laborator-07 perf.data
man perf-report
Interprète les données sauvegardées dans perf.data
après analyse à l'aide de perf record
. Ainsi pour l'exemple wget ci-dessus, nous avons:
$ perf report # Events: 13 cycles # # Overhead Command Shared Object Symbol # ........ ....... ................. ...... # 86.43% wget e8ee21 [.] 0x00000000e8ee21 11.03% wget [kernel.kallsyms] [k] prep_new_page 2.37% wget [kernel.kallsyms] [k] sock_aio_read 0.11% wget [kernel.kallsyms] [k] perf_event_comm 0.05% wget [kernel.kallsyms] [k] native_write_msr_safe
strace
intercepte et enregistre les appels système effectués par un processus et les signaux qu'il reçoit. Dans la forme la plus simple, strace exécute la commande spécifiée jusqu'à la fin du processus associé.
$strace cat /proc/cpuinfo execve("/bin/cat", ["cat", "/proc/cpuinfo"], [/* 30 vars */]) = 0 open("/proc/cpuinfo", O_RDONLY) = 3 read(3, "processor\t: 0\nvendor_id\t: Genuin"..., 32768) = 3652 write(1, "processor\t: 0$\nvendor_id\t: Genui"..., 7512) = 7512
Les options les plus courantes pour strace sont:
- f
, cette option sera suivie et les processus enfants créés par le processus actuel -o fichier
, par défaut, strace affiche les informations sur stderr. Avec cette option, la sortie sera placée dans le fichier de nom de fichier. -p pid
, pid du processus de suivi. - e expression
, modifie les appels que vous recherchez.iuliana@debian$ strace -f -e connect,socket,bind -p $(pidof iceweasel) Process 6429 attached with 30 threads - interrupt to quit socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 50 connect(50, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("141.85.227.65")}, 16) = -1 EINPROGRESS
Un autre utilitaire lié à strace est ltrace. Il suit les appels de la bibliothèque.
Le but d'un débogueur (par exemple, GDB, via la commande gdb) est de nous permettre d'inspecter ce qui se passe dans un programme en cours d'exécution ou à la fin de celui-ci lorsqu'une erreur fatale s'est produite sur la base du fichier coredump créé. par lui.
Valgrind est une suite d’utilitaires utilisés pour le débogage et le profilage. Parmi les outils ou outils les plus utilisés dans cette suite, citons:
memcheck
- Effectue une analyse d'utilisation de la mémoire cachegrind
- Effectue une analyse des performances du cache helgrind
- Utilisé pour résoudre les conditions d'exécution multithread.
Pour résoudre le labo, veuillez cloner repository. si vous en avez déjà un, lancez svp git pull
.
linux-tools
. Vous pouvez vérifier cela en exécutant la commande perf -help
. Si la commande est introuvable, vous devez installer le package:
student@so:~$ sudo apt-get update student@so:~$ sudo apt-get install linux-tools-4.15.0-34-generic
Le but de l’exercice est d’analyser le nombre d’instructions exécutées par le processeur en fonction d’un exécutable. Perf fournit un moyen d'extraire des données importantes du profilage grâce au support de script fourni par perf script
. Il fonctionne avec le record de performance
qui récupère la liste d'échantillons et l'enregistre dans le fichier perf.data
.
Allez dans le répertoire 1-custom
. La première étape consiste à générer le fichier perf.data
contenant les échantillons. Pour cela, lancez:
make sudo perf record -e cycles:pp -c 10000 -d ./hash
Utilisez la commande perf script
avec l'option -F
(recherchez 'man perf-script') afin de trouver le nombre total d'instructions de pointeur, puis celles contenues dans la fonction hash_search_index
. Ayant les deux valeurs, calculez le pourcentage de valeurs dans la fonction hash_search_index
.
wc -l
pour compter les lignes de sortie et grep pour filtrer après hash_search_index
. Pour faire des nombres rationnels, utilisez une commande comme echo 7/2 | bc -l
.
hash_search_index
. À l'aide du script perf, vous pouvez analyser les événements enregistrés dans les exemples de la méthode process_event. Pour plus d'informations sur perf script
, voir: man perf-script-python] ] et le [[https://lwn.net/Articles/620900/|exemple d'utilisation
Vérifiez le résultat à l'aide de la commande perf report
.
À l'aide de l'outil perf_3.2
, nous voulons déterminer si le langage C est major-colonne ou rang-majeur (rang-major-ordre).
Allez dans le répertoire 2-major
et remplissez le programme row.c
pour incrémenter les éléments d'une matrice sur des lignes, puis remplissez le programme columns.c
pour incrémenter les éléments d'un tableau de colonnes. .
Déterminez le nombre de caches manqués par rapport au nombre d'entrées de cache en utilisant state
pour suivre l'événement L1-dcache-load-misses
. Pour voir les événements disponibles, utilisez la commande perf list
. Utilisez le -e
de l'utilitaire 'perf' pour spécifier un événement de suivi spécifique.
Allez dans le répertoire 3-busy
et examinez le fichier busy.c
. Exécutez le programme occupé et analysez la charge du système à l'aide de la commande 'sudo perf top'. Quelle fonction le système semble-t-il charger?
Allez dans le répertoire 4-find-char
et analysez le contenu du fichier find-char.c
. Compilez le fichier find-char.c
et lancez l'exécutable.
Identifiez, à l'aide de perf record
et de perf report
, le processeur le plus fastidieux, et tentez d'améliorer les performances du programme.
Allez dans le répertoire 5-print
et regardez le contenu du fichier print.c
. Utilisez la commande “make print” pour compiler le programme “print”. Est le fichier Makefile?
Quel est l'ordre dans lequel les écritures de la console sont faites? Expliquez le résultat.
Mettez un sleep(5)
avant return 0
dans la fonction principale et utilisez la commande 'strace -e write ./print' pour trouver l'explication.
Allez dans le dossier 6-flowers
et analysez le contenu de flowers.c
. Compilez le fichier flowers.c
et lancez l'exécutable flowers
. Que se passe t-il Utilisez valgrind
avec l'option –tool = memcheck
. Affiche la valeur du troisième élément du tableau flowers
, c'est-à-dire flowers [2]
.
Allez dans le répertoire '7-exploit' et regardez le contenu du fichier 'exploit.c'. Utilisez la commande “make” pour compiler l'exécutable “exploit”. Identifiez un problème dans la fonction read_name
.
Utilisez gdb
pour examiner la pile avant de lancer l'appel read.
student@spook:~ gdb ./exploit (gdb) break read_name (gdb) run
Affiche les adresses des variables name
et access
.
(gdb) print/x &access (gdb) print/x &name
Notez que la différence entre l'adresse de la variable d'accès et le tampon de nom est 0x10 (16) octets, ce qui signifie que la variable d'accès se trouve immédiatement à la fin des données du tampon de nom. En utilisant vos informations, créez une entrée pratique que vous pouvez donner à l’exécutable de l’exploit pour qu’il vous montre la chaîne “Bon travail, vous m’avez piraté!”.
python -c
.
student@spook:~ python -c 'print "A"*8 + "\x01\x00\x00\x00"' | ./exploit
La commande ci-dessus générera 8 octets avec la valeur 'A' (code ASCII 0x41), un octet avec la valeur 0x01 et 3 autres octets avec la valeur 0x00 et le donnera à l'exécutable exploit stdin. Notez que les données sont structurées en mémoire au format endian petit. Ainsi, si les 4 derniers octets écrasent une adresse, elle sera interprétée comme étant 0x00000001, NO 0x01000000.
Allez dans le répertoire “8-mystery” où vous trouverez le mystère exécutable. Enquêter et expliquer ce qu'il fait.