Advertisement
Guest User

sbc-bench.sh

a guest
Jul 26th, 2018
327
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 12.18 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. Main() {
  4.     # check whether we're running in monitoring or benchmark mode
  5.     if [ "X$1" = "Xm" ]; then
  6.         interval=$2
  7.         MonitorBoard
  8.     else
  9.         SwitchToPerformance >/dev/null 2>&1
  10.         InstallPrerequisits
  11.         InitialMonitoring
  12.         RunTinyMemBench
  13.         Run7ZipBenchmark
  14.         RunOpenSSLBenchmark
  15.         FinalMonitoring
  16.     fi
  17. } # Main
  18.  
  19. SwitchToPerformance() {
  20.     CPUCores=$(grep -c '^processor' /proc/cpuinfo)
  21.     for ((i=0;i<CPUCores;i++)); do
  22.         echo performance >/sys/devices/system/cpu/cpu${i}/cpufreq/scaling_governor
  23.     done
  24. } # SwitchToPerformance
  25.  
  26. MonitorBoard() {
  27.     # In Armbian we can rely on /etc/armbianmonitor/datasources/soctemp
  28.     if [ -f /etc/armbianmonitor/datasources/soctemp ]; then
  29.         TempSource=/etc/armbianmonitor/datasources/soctemp
  30.     else
  31.         TempSource="$(mktemp /tmp/soctemp.XXXXXX)"
  32.         if [[ -d "/sys/devices/platform/a20-tp-hwmon" ]]; then
  33.             # Allwinner A20 with old 3.4 kernel
  34.             ln -fs /sys/devices/platform/a20-tp-hwmon/temp1_input ${TempSource}
  35.         elif [[ -f /sys/class/hwmon/hwmon0/temp1_input ]]; then
  36.             # usual convention with modern kernels
  37.             ln -fs /sys/class/hwmon/hwmon0/temp1_input ${TempSource}
  38.         else
  39.             # all other boards/kernels use the same sysfs node except of Actions Semi S500
  40.             # so on LeMaker Guitar, Roseapple Pi or Allo Sparky it must read "thermal_zone1"
  41.             ln -fs /sys/devices/virtual/thermal/thermal_zone0/temp ${TempSource}
  42.         fi
  43.     fi
  44.  
  45.     # Try to renice to 19 to not interfere with benchmark behaviour
  46.     renice 19 $BASHPID >/dev/null 2>&1
  47.  
  48.     LastUserStat=0
  49.     LastNiceStat=0
  50.     LastSystemStat=0
  51.     LastIdleStat=0
  52.     LastIOWaitStat=0
  53.     LastIrqStat=0
  54.     LastSoftIrqStat=0
  55.     LastCpuStatCheck=0
  56.     LastTotal=0
  57.  
  58.     SleepInterval=${interval:-5}
  59.  
  60.     if [ -f /usr/bin/vcgencmd ]; then
  61.         DisplayHeader="Time        fake/real   load %cpu %sys %usr %nice %io %irq    CPU   VCore"
  62.         CPUs=raspberrypi
  63.     elif [ -f /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq ]; then
  64.         DisplayHeader="Time       big.LITTLE   load %cpu %sys %usr %nice %io %irq    CPU"
  65.         CPUs=biglittle
  66.     elif [ -f /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq ]; then
  67.         DisplayHeader="Time        CPU    load %cpu %sys %usr %nice %io %irq    CPU"
  68.         CPUs=normal
  69.     else
  70.         DisplayHeader="Time      CPU n/a    load %cpu %sys %usr %nice %io %irq    CPU"
  71.         CPUs=notavailable
  72.     fi
  73.     [ -f "${TempSource}" ] || SocTemp='n/a'
  74.     echo -e "${DisplayHeader}"
  75.     while true ; do
  76.         LoadAvg=$(cut -f1 -d" " </proc/loadavg)
  77.         if [ "X${SocTemp}" != "Xn/a" ]; then
  78.             read SocTemp <"${TempSource}"
  79.             if [ ${SocTemp} -ge 1000 ]; then
  80.                 SocTemp=$(awk '{printf ("%0.1f",$1/1000); }' <<<${SocTemp})
  81.             fi
  82.         fi
  83.         case ${CPUs} in
  84.             raspberrypi)
  85.                 FakeFreq=$(awk '{printf ("%0.0f",$1/1000); }' </sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq) 2>/dev/null
  86.                 RealFreq=$(/usr/bin/vcgencmd measure_clock arm | awk -F"=" '{printf ("%0.0f",$2/1000000); }' )
  87.                 CoreVoltage=$(/usr/bin/vcgencmd measure_volts | cut -f2 -d= | sed 's/000//')
  88.                 ProcessStats
  89.                 echo -e "$(date "+%H:%M:%S"): $(printf "%4s" ${FakeFreq})/$(printf "%4s" ${RealFreq})MHz $(printf "%5s" ${LoadAvg}) ${procStats}  $(printf "%4s" ${SocTemp})°C  ${CoreVoltage}"
  90.                 ;;
  91.             biglittle)
  92.                 BigFreq=$(awk '{printf ("%0.0f",$1/1000); }' </sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq) 2>/dev/null
  93.                 LittleFreq=$(awk '{printf ("%0.0f",$1/1000); }' </sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq) 2>/dev/null
  94.                 ProcessStats
  95.                 echo -e "$(date "+%H:%M:%S"): $(printf "%4s" ${BigFreq})/$(printf "%4s" ${LittleFreq})MHz $(printf "%5s" ${LoadAvg}) ${procStats}  $(printf "%4s" ${SocTemp})°C"
  96.                 ;;
  97.             normal)
  98.                 CpuFreq=$(awk '{printf ("%0.0f",$1/1000); }' </sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq) 2>/dev/null
  99.                 ProcessStats
  100.                 echo -e "$(date "+%H:%M:%S"): $(printf "%4s" ${CpuFreq})MHz $(printf "%5s" ${LoadAvg}) ${procStats}  $(printf "%4s" ${SocTemp})°C"
  101.                 ;;
  102.             notavailable)
  103.                 ProcessStats
  104.                 echo -e "$(date "+%H:%M:%S"):   ---     $(printf "%5s" ${LoadAvg}) ${procStats}  $(printf "%4s" ${SocTemp})°C"
  105.                 ;;
  106.         esac
  107.         sleep ${SleepInterval}
  108.     done
  109. } # MonitorBoard
  110.  
  111. ProcessStats() {
  112.     procStatLine=(`sed -n 's/^cpu\s//p' /proc/stat`)
  113.     UserStat=${procStatLine[0]}
  114.     NiceStat=${procStatLine[1]}
  115.     SystemStat=${procStatLine[2]}
  116.     IdleStat=${procStatLine[3]}
  117.     IOWaitStat=${procStatLine[4]}
  118.     IrqStat=${procStatLine[5]}
  119.     SoftIrqStat=${procStatLine[6]}
  120.  
  121.     Total=0
  122.     for eachstat in ${procStatLine[@]}; do
  123.         Total=$(( ${Total} + ${eachstat} ))
  124.     done
  125.  
  126.     UserDiff=$(( ${UserStat} - ${LastUserStat} ))
  127.     NiceDiff=$(( ${NiceStat} - ${LastNiceStat} ))
  128.     SystemDiff=$(( ${SystemStat} - ${LastSystemStat} ))
  129.     IOWaitDiff=$(( ${IOWaitStat} - ${LastIOWaitStat} ))
  130.     IrqDiff=$(( ${IrqStat} - ${LastIrqStat} ))
  131.     SoftIrqDiff=$(( ${SoftIrqStat} - ${LastSoftIrqStat} ))
  132.    
  133.     diffIdle=$(( ${IdleStat} - ${LastIdleStat} ))
  134.     diffTotal=$(( ${Total} - ${LastTotal} ))
  135.     diffX=$(( ${diffTotal} - ${diffIdle} ))
  136.     CPULoad=$(( ${diffX}* 100 / ${diffTotal} ))
  137.     UserLoad=$(( ${UserDiff}* 100 / ${diffTotal} ))
  138.     SystemLoad=$(( ${SystemDiff}* 100 / ${diffTotal} ))
  139.     NiceLoad=$(( ${NiceDiff}* 100 / ${diffTotal} ))
  140.     IOWaitLoad=$(( ${IOWaitDiff}* 100 / ${diffTotal} ))
  141.     IrqCombined=$(( ${IrqDiff} + ${SoftIrqDiff} ))
  142.     IrqCombinedLoad=$(( ${IrqCombined}* 100 / ${diffTotal} ))
  143.  
  144.     LastUserStat=${UserStat}
  145.     LastNiceStat=${NiceStat}
  146.     LastSystemStat=${SystemStat}
  147.     LastIdleStat=${IdleStat}
  148.     LastIOWaitStat=${IOWaitStat}
  149.     LastIrqStat=${IrqStat}
  150.     LastSoftIrqStat=${SoftIrqStat}
  151.     LastTotal=${Total}
  152.     procStats=$(echo -e "$(printf "%3s" ${CPULoad})%$(printf "%4s" ${SystemLoad})%$(printf "%4s" ${UserLoad})%$(printf "%4s" ${NiceLoad})%$(printf "%4s" ${IOWaitLoad})%$(printf "%4s" ${IrqCombinedLoad})%")
  153. } # ProcessStats
  154.  
  155. InstallPrerequisits() {
  156.     echo -e "Installing needed tools. This may take some time...\c"
  157.     SevenZip=$(which 7za || which 7zr)
  158.     [ -z "${SevenZip}" ] && apt -f -qq -y install p7zip && SevenZip=/usr/bin/7zr >/dev/null 2>&1
  159.     [ -z "${SevenZip}" ] && (echo "No 7-zip binary found and could not be installed. Aborting" >&2 ; exit 1)
  160.  
  161.     which iostat >/dev/null 2>&1 || apt -f -qq -y install sysstat >/dev/null 2>&1
  162.     which git >/dev/null 2>&1 || apt -f -qq -y install git >/dev/null 2>&1
  163.     which openssl >/dev/null 2>&1 || apt -f -qq -y install openssl >/dev/null 2>&1
  164.  
  165.     # get/build tinymembench if not already there
  166.     if [ ! -x /tmp/tinymembench/tinymembench ]; then
  167.         cd /tmp
  168.         git clone https://github.com/ssvb/tinymembench >/dev/null 2>&1
  169.         cd tinymembench
  170.         make >/dev/null 2>&1
  171.     fi
  172. } # InstallPrerequisits
  173.  
  174. InitialMonitoring() {
  175.     TempDir="$(mktemp -d /tmp/${0##*/}.XXXXXX)"
  176.     TempLog="${TempDir}/temp.log"
  177.     ResultLog="${TempDir}/results.log"
  178.     MonitorLog="${TempDir}/monitor.log"
  179.     trap "rm -rf \"${TempDir}\" ; exit 0" 0 1 2 3 15
  180.     [ -f /etc/armbian-release ] && (grep -v "#" /etc/armbian-release ; echo "") >${ResultLog}
  181.     which lsb_release >/dev/null 2>&1 && (lsb_release -a 2>/dev/null) >>${ResultLog}
  182.     [ -f /etc/armbian-release ] || echo -e "Architecture:\t$(dpkg --print-architecture)\n" >>${ResultLog}
  183.     echo -e "$(uname -a)\n\n$(uptime)\n\n$(iostat)\n\n$(free -h)\n\n$(cat /proc/swaps 2>/dev/null)\n" \
  184.         >>${ResultLog}
  185.     # Check cpufreq statistics prior and after benchmark to detect throttling (won't work on
  186.     # the RPi since RPi Trading folks are cheaters. Cpufreq support via sysfs is bogus and
  187.     # with latest ThreadX (firmware) update they even cheat wrt 'vcgencmd get_throttled'
  188.     # https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=217056#p1334921
  189.     find /sys -name time_in_state | while read ; do
  190.         Number=$(echo ${REPLY} | tr -c -d '[:digit:]')
  191.         Entries=$(wc -l ${REPLY} | awk -F" " '{print $1}')
  192.         head -n $(( ${Entries} - 1 )) ${REPLY} >${TempDir}/time_in_state_before_${Number}
  193.     done
  194. } # InitialMonitoring
  195.  
  196. RunTinyMemBench() {
  197.     echo -e " Done.\nExecuting tinymembench. This will take a long time...\c"
  198.     echo -e "System health while running tinymembench:\n" >${MonitorLog}
  199.     "${0}" m 60 >>${MonitorLog} &
  200.     MonitoringPID=$!
  201.     sleep 10
  202.     if [ ${CPUCores} -gt 4 ]; then
  203.         # big.LITTLE SoC, we execute one time on a little and one time on a big core
  204.         echo -e "Executing tinymembench on a little core:\n" >${TempLog}
  205.         taskset -c 0 /tmp/tinymembench/tinymembench >>${TempLog} 2>&1
  206.         echo -e "\nExecuting tinymembench on a big core:\n" >>${TempLog}
  207.         taskset -c $(( ${CPUCores} -1 )) /tmp/tinymembench/tinymembench >>${TempLog} 2>&1
  208.     else
  209.         /tmp/tinymembench/tinymembench >${TempLog} 2>&1
  210.     fi
  211.     kill ${MonitoringPID}
  212.     cat ${TempLog} >>${ResultLog}
  213. } # RunTinyMemBench
  214.  
  215. Run7ZipBenchmark() {
  216.     echo -e " Done.\nExecuting 7-zip benchmark. This will take a long time...\c"
  217.     echo -e "\nSystem health while running 7-zip single core benchmark:\n" >>${MonitorLog}
  218.     echo -e "\c" >${TempLog}
  219.     "${0}" m 15 >>${MonitorLog} &
  220.     MonitoringPID=$!
  221.     if [ ${CPUCores} -gt 4 ]; then
  222.         # big.LITTLE SoC, we execute one time on a little and one time on a big core
  223.         taskset -c 0 "${SevenZip}" b >>${TempLog}
  224.         taskset -c $(( ${CPUCores} - 1 )) "${SevenZip}" b >>${TempLog}
  225.     else
  226.         taskset -c 0 "${SevenZip}" b >>${TempLog}
  227.     fi
  228.     kill ${MonitoringPID}
  229.     cat ${TempLog} >>${ResultLog}
  230.     echo -e "\nSystem health while running 7-zip multi core benchmark:\n" >>${MonitorLog}
  231.     echo -e "\c" >${TempLog}
  232.     "${0}" m 45 >>${MonitorLog} &
  233.     MonitoringPID=$!
  234.     RunHowManyTimes=3
  235.     sleep 10
  236.     for ((i=1;i<=RunHowManyTimes;i++)); do
  237.         "${SevenZip}" b >>${TempLog}
  238.     done
  239.     kill ${MonitoringPID}
  240.     cat ${TempLog} >>${ResultLog}
  241.     sed -i 's/|//' ${TempLog}
  242.     CompScore=$(awk -F" " '/^Avr:/ {print $4}' <${TempLog} | tr '\n' ', ' | sed 's/,$//')
  243.     DecompScore=$(awk -F" " '/^Avr:/ {print $7}' <${TempLog} | tr '\n' ', ' | sed 's/,$//')
  244.     TotScore=$(awk -F" " '/^Tot:/ {print $4}' <${TempLog} | tr '\n' ', ' | sed 's/,$//')
  245.     echo -e "\nCompression: ${CompScore}" >>${ResultLog}
  246.     echo -e "Decompression: ${DecompScore}" >>${ResultLog}
  247.     echo -e "Total: ${TotScore}\n" >>${ResultLog}
  248. } # Run7ZipBenchmark
  249.  
  250. RunOpenSSLBenchmark() {
  251.     echo -e " Done.\nExecuting OpenSSL benchmark. This will take a long time...\c"
  252.     echo -e "\nSystem health while running OpenSSL benchmark:\n" >>${MonitorLog}
  253.     "${0}" m 10 >>${MonitorLog} &
  254.     MonitoringPID=$!
  255.     sleep 10
  256.     for i in 128 192 256 ; do
  257.         if [ ${CPUCores} -gt 4 ]; then
  258.             # big.LITTLE SoC, we execute one time on a little and one time on a big core
  259.             taskset -c 0 openssl speed -elapsed -evp aes-${i}-cbc 2>/dev/null
  260.             taskset -c $(( ${CPUCores} -1 )) openssl speed -elapsed -evp aes-${i}-cbc 2>/dev/null
  261.         else
  262.             openssl speed -elapsed -evp aes-${i}-cbc 2>/dev/null
  263.             openssl speed -elapsed -evp aes-${i}-cbc 2>/dev/null
  264.         fi
  265.     done >${TempLog}
  266.     kill ${MonitoringPID}
  267.     echo -e "$(openssl version)\n$(grep '^type' ${TempLog} | head -n1)" >>${ResultLog}
  268.     grep '^aes-' ${TempLog} >>${ResultLog}
  269. } # RunOpenSSLBenchmark
  270.  
  271. FinalMonitoring() {
  272.     echo -e " Done.\n"
  273.     [ ${CPUCores} -gt 4 ] && BigLittle=" (on big.LITTLE systems measured individually)"
  274.     find /sys -name time_in_state | while read ; do
  275.         Number=$(echo ${REPLY} | tr -c -d '[:digit:]')
  276.         Entries=$(wc -l ${REPLY} | awk -F" " '{print $1}')
  277.         head -n $(( ${Entries} - 1 )) ${REPLY} >${TempDir}/time_in_state_after_${Number}
  278.         diff ${TempDir}/time_in_state_after_${Number} ${TempDir}/time_in_state_before_${Number} >/dev/null 2>&1 \
  279.             || echo -e "ATTENTION: Throttling occured on CPU cluster ${Number}. Check the uploaded log for details."
  280.     done
  281.     echo -e "\nBelow benchmark results:\n"
  282.     echo -e "\n\nMonitoring data for each run:\n" >>${ResultLog}
  283.     cat ${MonitorLog} >>${ResultLog}
  284.     echo -e "\n\n$(iostat)\n\n$(free -h)\n\n$(cat /proc/swaps 2>/dev/null)\n" >>${ResultLog}
  285.     [ -f /boot/config.txt ] && echo -e "/boot/config.txt:\n$(grep -v '#' /boot/config.txt | sed '/^\s*$/d')\n" >>${ResultLog}
  286.     UploadURL=$(curl -s -F 'f:1=<-' ix.io <${ResultLog} 2>/dev/null || curl -s -F 'f:1=<-' ix.io <${ResultLog} 2>/dev/null)
  287.     echo -e "Memory performance${BigLittle}:"
  288.     awk -F" " '/^ standard/ {print $2": "$4" "$5" "$6}' <${ResultLog}
  289.     echo -e "\n7-zip total scores (three runs): $(awk -F" " '/^Total:/ {print $2}' ${ResultLog})"
  290.     echo -e "\nOpenSSL results${BigLittle}:\n$(grep '^type' ${TempLog} | head -n1)"
  291.     grep '^aes-' ${TempLog}
  292.     echo -e "\nFull results uploaded to ${UploadURL}. Please check the log for anomalies (e.g. swapping\nor throttling happenend) and otherwise share this URL.\n"
  293. } # FinalMonitoring
  294.  
  295. Main "$@"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement