38

I want to see if my process makes a lot of context switches. I also want to see how manpulating task groups affects the number of context switches.

3
  • What OS? What version? What kernel?
    – Mikel
    May 25, 2012 at 16:48
  • GNU/Linux 2.6.18
    – luntain
    May 25, 2012 at 17:28
  • 5
    Check /proc/[pid]/status
    – Kevin
    May 25, 2012 at 17:34

7 Answers 7

43

You can view information about your process's context switches in /proc/<pid>/status.

$ pid=307
$ grep ctxt /proc/$pid/status
voluntary_ctxt_switches:        41
nonvoluntary_ctxt_switches:     16

To see these numbers updating continuously, run

$ # Update twice a second.
$ watch -n.5 grep ctxt /proc/$pid/status

To get just the numbers, run

$ grep ctxt /proc/$pid/status | awk '{ print $2 }'
5
  • I tried the above watch command but the output is just 1 (for voluntary and involuntary context switch). My linux kernal version is 2.6.39-400.214.4.el6uek.x86_64. Is the output dependant on the linux version? Mar 19, 2015 at 6:49
  • Paste your output here please.
    – user26112
    Mar 20, 2015 at 19:05
  • Its the same as mentioned in the answere - "watch -n.5 grep ctxt /proc/5647/status" Mar 21, 2015 at 10:52
  • I have to use procfs but on old kernels there aren't the values inside /proc/.../status. any suggestion ?
    – Massimo
    Aug 31, 2018 at 17:49
  • What If the process is small and stops running quickly? Feb 21, 2020 at 11:59
13

pidstat(1) - Report statistics for Linux tasks. According to man pidstat it's so easy as just pidstat -w …

4
  • I executed "watch -n0.5 pidstat -w -I -p 5876" command but the output is 0 (for both cswch/s nvcswch/s). Does this command work for linux version - 2.6.39-400.214.4.el6uek.x86_64 ? Mar 19, 2015 at 6:52
  • This command should work just fine. But beware you're using it wrong because when you don't specify report interval „tasks statistics are to be reported for the time since system startup (boot).” similar to vmstat, iostat and others. So if current statistics is needed instead of watch'ing simply run it with one second interval.
    – poige
    Mar 19, 2015 at 12:46
  • If I don't do watch, how do I see the numbers updating continuously? Executing the command "pidstat -w -I -p 5876 5" the command just waits for 5 seconds and then prints the output (again as 0). It does not run continuously as I was expecting (I know that this is contradicting to what pidstat's man page says - linux.die.net/man/1/pidstat). My OS is Oracle Linux Server 6.4. Mar 21, 2015 at 10:57
  • Does ` pidstat -w -l -p SELF 1` work for you?
    – poige
    Mar 21, 2015 at 16:11
5

See man getrusage which will let you query the number of voluntary and involuntary context switches.

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 */
};

You can tell it to report per-thread information, like this:

struct rusage usage;
getrusage( RUSAGE_THREAD, &usage );

Just call it twice, before and after your critical section, and see if usage.ru_nivcsw value has increased or not.

1
  • Similarly, in Golang: syscall.Getrusage(syscall.RUSAGE_SELF, &usage) May 26, 2022 at 2:44
4

To get a record of an entire process run, you can use the GNU time utility (don't confuse it with the bash builtin) with the -v option. Here's an example with unrelated lines of output removed:

$ `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
4

You can use, sar -w. For instance, sar -w 1 3, reports total number of context switches per second for every 1 seconds a total of 3 times.

1
  • 1
    That doesn't work "out of the box" on many systems, even if the command is available. Can you include in your answer how to enable data collecting for sar?
    – Anthon
    May 2, 2016 at 5:40
2

Write the following script to file (ctx.sh). with ctx.sh <core> you will see all the processes running on a given core and changing nv-context switches will be highlighted. Looking at this, you will be able to identify which are the competing processes for the core.

#!/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
0
sudo perf stat -e context-switches -I 1000 PROCESS_NAME

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .