Getting real time CPU stats while benchmarking

As of late I have been spending a lot of time working with a client to benchmark their software. We needed a way to get the cost per core on the system. We would start by limiting the software to one core, run tests and log results repeat with two cores etc. The stats were all over the place. We were not able to explain why certain CPU’s behaved one way and others a different way. We tried looking at the generation chip, the type of ram etc. and we did not have anything conclusive. After digging around a bit I learned from those wiser then myself that the CPU clock speed can vary based on many fractures such as the TDP of the chip, how well the chassis handles heat dissipation etc.  The most accurate way to get the CPU stats is by looking at each CPU’s current performance. For instance if we wanted to look at CPU0 we would do:

root@raspberrypi:~# cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
1200000
root@raspberrypi:~#

If we have 4 CPU’s on the box we may want to do this:

root@raspberrypi:~# cat /sys/devices/system/cpu/cpu[0-3]/cpufreq/cpuinfo_cur_freq
600000
600000
600000
600000
root@raspberrypi:~#

Running these commands manually can be hard so if you have a quick eye and want to watch things in real time you can do:

watch -n 0 cat /sys/devices/system/cpu/cpu[0-3]/cpufreq/cpuinfo_cur_freq

In order to make things easier for myself I wrote a quick bash script that checked ever 500ms each CPU and kept stats. This makes it easy to lave it running in the background to get an overall average of how the CPU is performing over a certain Period.

#!/bin/bash
PROC_COUNT=$(nproc --all)
echo "Running as PID $$. To get the stats simply do Control+C"

trap 'sigint' INT
trap ':' HUP # ignore the specified signals

sigint()
	{
	echo ""
	for ((j=0; j<PROC_COUNT; j++)); do
		AVG=$((${CPU_S[$j]} / "${CPU_C[$j]}"))
		echo "Core $j had an AVG USAGE of $AVG"
	done
	exit 0
	}

 

while :
do

for ((i=0; i<PROC_COUNT; i++)); do
	CPU_C[$i]=$((${CPU_C[$i]} + 1))
	MY_CPU_T=$(cat /sys/devices/system/cpu/cpu$i/cpufreq/cpuinfo_cur_freq)
	CPU_S[$i]=$((${CPU_S[$i]} + "$MY_CPU_T"))
	done
	sleep 0.05
done