Je veux voir si mon processus fait beaucoup de changements de contexte. Je veux également voir comment la manipulation des groupes de tâches affecte le nombre de changements de contexte.
Vous pouvez afficher des informations sur les changements de contexte de votre processus dans /proc/<pid>/status
.
$ pid=307
$ grep ctxt /proc/$pid/status
voluntary_ctxt_switches: 41
nonvoluntary_ctxt_switches: 16
Pour voir ces chiffres se mettre à jour en continu, exécutez
$ # Update twice a second.
$ watch -n.5 grep ctxt /proc/$pid/status
Pour obtenir uniquement les chiffres, exécutez
$ grep ctxt /proc/$pid/status | awk '{ print $2 }'
pidstat (1) - Rapporte les statistiques des tâches Linux. Selon man pidstat
c'est aussi simple que juste pidstat -w …
Pour obtenir un enregistrement de l'exécution d'un processus entier, vous pouvez utiliser l'utilitaire GNU time
(ne le confondez pas avec le programme intégré bash
) avec le -v
option. Voici un exemple avec des lignes de sortie non liées supprimées:
$ `which time` -v ls
a.out exception_Finder.cpp log.txt
Command being timed: "ls"
...
Voluntary context switches: 1
Involuntary context switches: 2
...
Exit status: 0
Vous pouvez utiliser, sar -w
. Par exemple, sar -w 1 3
, rapporte un nombre total de changements de contexte par seconde pour chaque 1 seconde au total 3 fois.
Écrivez le script suivant dans le fichier (ctx.sh
). avec ctx.sh <core>
vous verrez tous les processus en cours d'exécution sur un noyau donné et la modification des commutateurs de contexte nv sera mise en évidence. En regardant cela, vous serez en mesure d'identifier quels sont les processus concurrents pour le noyau.
#!/bin/bash
if [[ $# -eq 0 ]]
then
echo "Usage:"
echo "$0 <core>"
exit 1
fi
if [[ -z $2 ]]
then
watch -d -n .2 $0 $1 nw
fi
ps -Leo lastcpu:1,tid,comm | grep "^$1 " | awk '{printf $3": ";system("cut -d\" \" -f3 /proc/"$2"/task/"$2"/schedstat 2>/dev/null")}' | sort -k 1 | column -t
Voir man getrusage qui vous permettra d'interroger le nombre de changements de contexte volontaires et involontaires.
struct rusage {
struct timeval ru_utime; /* user CPU time used */
struct timeval ru_stime; /* system CPU time used */
long ru_maxrss; /* maximum resident set size */
long ru_ixrss; /* integral shared memory size */
long ru_idrss; /* integral unshared data size */
long ru_isrss; /* integral unshared stack size */
long ru_minflt; /* page reclaims (soft page faults) */
long ru_majflt; /* page faults (hard page faults) */
long ru_nswap; /* swaps */
long ru_inblock; /* block input operations */
long ru_oublock; /* block output operations */
long ru_msgsnd; /* IPC messages sent */
long ru_msgrcv; /* IPC messages received */
long ru_nsignals; /* signals received */
long ru_nvcsw; /* voluntary context switches */
long ru_nivcsw; /* involuntary context switches */
};
Vous pouvez lui indiquer de rapporter des informations par thread, comme ceci:
struct rusage usage;
getrusage( RUSAGE_THREAD, &usage );
Appelez-le simplement deux fois, avant et après votre section critique, et voyez si la valeur usage.ru_nivcsw a augmenté ou non.
Sudo perf stat -e context-switches -I 1000 PROCESS_NAME