1

I have a Centos7 system on a Google cloud machine, running a multithreaded database server that executes a particular set of queries in 70 secs (plus or minus 1 sec). I want to know how many context switches the server makes running this workload.

The server pid is 11850.

I used 3 different counting methods:

method 1:

start

perf -e context-switches -p 11850

in one window and immediately run the database client in another window. Then kill perf as soon as the client completes.

The resulting output is

 Performance counter stats for process id '11850':

     5,831,206      context-switches          #    0.004 M/sec

    70.607962486 seconds time elapsed

Method 2

start

pidstat -tw -p 11850 70 1 >pidstat.out

in one window and immediately run the client in another window.

Both pidstat and the client will complete within a second of each other. When that happens add all the values of cswch/s and nvcswch/s in pidstat.out and multiply the result by 70.

This gives an almost identical result to what Method 1 does.

Method 3

Run a script containing the following commands in one window

vmstat -s|grep "CPU context switches" 
sleep 70
vmstat -s|grep "CPU context switches" 

and then immediately run the client in another window. Both the client and the 2nd vmstat will finish within a second of each other.

The vmstat outputs are

    439394923 CPU context switches
    450457926 CPU context switches

Subtracting the first number from the 2nd gives 11,063,003 which is almost double the result of the other two methods.

Since nothing else was running on the system, and the normal rate of context switches on an idle system is about 100/sec, it appears that the vmstat method is double counting context switches.

Is this a bug, or am I missing something?

2 Answers2

1

The assumption that only the examined PID does context switches needs examining.

Review context switches across all CPUs, such as with perf top -e context-switches -a. Probably you will see other tasks, including other database threads and kernel things, jumping on and off CPU.

More useful than just a context switch counter would be stats like instructions per cycle. Get those with perf stat. Good IPC is greater than one. Of course, for CPU bound workloads. Slow storage means an eternity of the CPU waiting.

John Mahowald
  • 30,009
  • 1
  • 17
  • 32
  • You hit the nail on the head. Non database threads, which are normally dormant an an idle machine, come to life during my database workload, and account for the extra context switches shown by Method3. As for obtaining the IPC, hardware performance counters are not exposed on many virtual machines -- particularly virtual machines from cloud providers. – Richard Gostanian Nov 12 '19 at 02:15
0

If you want to get the number of context switches from within a process, you can look into the GetRUsage syscall.

For example, in Golang:

    var usage syscall.Rusage
    if err := syscall.Getrusage(syscall.RUSAGE_SELF, &usage); err != nil {
        fmt.Printf("Error: unable to gather resource usage data: %v\n", err)
    }