Réponses:
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 si facile que justepidstat -w …
vmstat
, iostat
et d' autres. Donc, si des statistiques actuelles sont nécessaires au lieu de watch
simplement les exécuter avec un intervalle d'une seconde.
Pour obtenir un enregistrement de l'exécution d'un processus entier, vous pouvez utiliser l' time
utilitaire GNU (ne le confondez pas avec le programme bash
intégré) avec l' -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
signale un nombre total de changements de contexte par seconde pour chaque 1 seconde au total 3 fois.
sar
?
Écrivez le script suivant dans file ( 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.