#!/bin/bash # kernbench by Con Kolivas <kernbench@kolivas.org> # based on a benchmark by Martin J. Bligh trap 'echo "ABORTING";exit' 1 2 15 VERSION=0.42 num_runs=5 single_runs=0 half_runs=1 opti_runs=1 max_runs=1 fast_run=0 while getopts vsHOMn:o:hf i do case $i in h) echo "kernbench v$VERSION by Con Kolivas <kernbench@kolivas.org>" echo "Usage:" echo "kernbench [-n runs] [-o jobs] [-s] [-H] [-O] [-M] [-h] [-v]" echo "n : number of times to perform benchmark (default 5)" echo "o : number of jobs for optimal run (default 4 * cpu)" echo "s : perform single threaded runs (default don't)" echo "H : don't perform half load runs (default do)" echo "O : don't perform optimal load runs (default do)" echo "M : don't perform maximal load runs (default do)" echo "f : fast run" echo "h : print this help" echo "v : print version number" exit ;; v) echo "kernbench Version $VERSION by Con Kolivas <kernbench@kolivas.org>" ; exit ;; n) nruns=$OPTARG ;; o) optijobs=$OPTARG ;; s) single_runs=1 ;; H) half_runs=0 ;; O) opti_runs=0 ;; M) max_runs=0 ;; f) fast_run=1 ;; esac done if [[ ! -f include/linux/kernel.h ]] ; then echo "No kernel source found; exiting" exit fi for i in time awk yes date do iname=`which $i` if [[ ! -a $iname ]] ; then echo "$i not found in path, please install it; exiting" exit fi done time=`which time` if [[ $nruns -gt 0 ]] ; then num_runs=$nruns elif [[ $fast_run -eq 1 ]]; then echo "Dropping to 3 runs for fast run" num_runs=3 fi if (($num_runs < 1)) ; then echo "Nothing to do; exiting" exit fi if (($num_runs > 10)) ; then echo "Are you crazy? trimming number of runs to 10" num_runs=10 fi if [[ ! -d /proc ]] ; then echo "Can't find proc filesystem; exiting" exit fi mem=`awk '/MemTotal/ {print $2}' /proc/meminfo` if [[ $mem -lt 4000000 && $max_runs -gt 0 ]] ; then echo Less than 4Gb ram detected! echo Maximal loads will not measure cpu throughput and may cause a swapstorm! echo If you did not plan this, -M flag is recommended to bypass maximal load. fi (( single_runs *= $num_runs )) (( half_runs *= $num_runs )) (( opti_runs *= $num_runs )) (( max_runs *= $num_runs )) cpus=`grep -c ^processor /proc/cpuinfo` echo $cpus cpus found echo Cleaning source tree... make clean > /dev/null 2>&1 if [[ $fast_run -eq 0 ]] ; then echo Caching kernel source in ram... for i in `find -type f` do cat $i > /dev/null done fi if [[ ! -f .config ]] ; then echo No old config found, using defconfig echo Making mrproper make mrproper > /dev/null 2>&1 echo Making defconfig... make defconfig > /dev/null 2>&1 else echo Making oldconfig... yes "" | make oldconfig > /dev/null 2>&1 fi halfjobs=$(( $cpus / 2 )) optijobs=${optijobs:=$(( $cpus * 4 ))} if [[ $halfjobs -lt 2 ]] ; then echo "Half load is no greater than single; disabling" half_runs=0 elif [[ $halfjobs -eq 2 ]] ; then echo "Half load is 2 jobs, changing to 3 as a kernel compile won't guarantee 2 jobs" halfjobs=3 fi echo Kernel `uname -r` echo Performing $num_runs runs of if [[ $single_runs -gt 0 ]] ; then echo make fi if [[ $half_runs -gt 0 ]] ; then echo make -j $halfjobs fi if [[ $opti_runs -gt 0 ]] ; then echo make -j $optijobs fi if [[ $max_runs -gt 0 ]] ; then echo make -j fi echo echo All data logged to kernbench.log if [[ $fast_run -eq 0 ]] ; then echo Warmup run... make -j $optijobs > /dev/null 2>&1 fi date >> kernbench.log uname -r >> kernbench.log add_data_point() { echo $@ | awk '{printf "%.6f %.6f %d", $1 + $2, $1 * $1 + $3, $4 + 1}' } show_statistics() { case $3 in 0) echo "No data" ;; 1) echo $1 ;; *) avg=`echo $1 $3 | awk '{print $1 / $2}'` var=`echo $1 $2 $3 | awk '{print ($2 - ($1 * $1) / $3) / ($3 - 1)}'` sdev=`echo $var | awk '{print $1^0.5}'` echo "$avg ($sdev)" ;; esac } do_log() { echo "Average $runname Run (std deviation):" > templog echo Elapsed Time `show_statistics $temp_elapsed` >> templog echo User Time `show_statistics $temp_user` >> templog echo System Time `show_statistics $temp_sys` >> templog echo Percent CPU `show_statistics $temp_percent` >> templog echo Context Switches `show_statistics $temp_ctx` >> templog echo Sleeps `show_statistics $temp_sleeps` >> templog echo >> templog cat templog cat templog >> kernbench.log } do_runs() { temp_elapsed="a" for (( i=1 ; i <= temp_runs ; i++ )) do echo $runname run number $i... make clean > /dev/null 2>&1 sync if [[ $fast_run -eq 0 ]] ; then sleep 5 fi $time -f "%e %U %S %P %c %w" -o timelog make -j $tempjobs > /dev/null 2>&1 read elapsed_time user_time sys_time percent ctx sleeps <timelog temp_elapsed=`add_data_point $elapsed_time $temp_elapsed` temp_user=`add_data_point $user_time $temp_user` temp_sys=`add_data_point $sys_time $temp_sys` temp_percent=`add_data_point $percent $temp_percent` temp_ctx=`add_data_point $ctx $temp_ctx` temp_sleeps=`add_data_point $sleeps $temp_sleeps` done if [[ $temp_runs -ne 0 ]] ; then do_log fi } temp_runs=$single_runs tempjobs=1 runname="Single threaded" do_runs temp_runs=$half_runs tempjobs=$halfjobs runname="Half load -j $halfjobs" do_runs temp_runs=$opti_runs tempjobs=$optijobs runname="Optimal load -j $optijobs" do_runs temp_runs=$max_runs tempjobs="" runname="Maximal load -j" do_runs