tbench.sh 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #!/bin/sh
  2. # SPDX-License-Identifier: GPL-2.0
  3. # Testing and monitor the cpu desire performance, frequency, load,
  4. # power consumption and throughput etc.when this script trigger tbench
  5. # test cases.
  6. # 1) Run tbench benchmark on specific governors, ondemand or schedutil.
  7. # 2) Run tbench benchmark comparative test on acpi-cpufreq kernel driver.
  8. # 3) Get desire performance, frequency, load by perf.
  9. # 4) Get power consumption and throughput by amd_pstate_trace.py.
  10. # 5) Analyse test results and save it in file selftest.tbench.csv.
  11. # 6) Plot png images about performance, energy and performance per watt for each test.
  12. # protect against multiple inclusion
  13. if [ $FILE_TBENCH ]; then
  14. return 0
  15. else
  16. FILE_TBENCH=DONE
  17. fi
  18. tbench_governors=("ondemand" "schedutil")
  19. # $1: governor, $2: round, $3: des-perf, $4: freq, $5: load, $6: performance, $7: energy, $8: performance per watt
  20. store_csv_tbench()
  21. {
  22. echo "$1, $2, $3, $4, $5, $6, $7, $8" | tee -a $OUTFILE_TBENCH.csv > /dev/null 2>&1
  23. }
  24. # clear some special lines
  25. clear_csv_tbench()
  26. {
  27. if [ -f $OUTFILE_TBENCH.csv ]; then
  28. sed -i '/Comprison(%)/d' $OUTFILE_TBENCH.csv
  29. sed -i "/$(scaling_name)/d" $OUTFILE_TBENCH.csv
  30. fi
  31. }
  32. # find string $1 in file csv and get the number of lines
  33. get_lines_csv_tbench()
  34. {
  35. if [ -f $OUTFILE_TBENCH.csv ]; then
  36. return `grep -c "$1" $OUTFILE_TBENCH.csv`
  37. else
  38. return 0
  39. fi
  40. }
  41. pre_clear_tbench()
  42. {
  43. post_clear_tbench
  44. rm -rf tbench_*.png
  45. clear_csv_tbench
  46. }
  47. post_clear_tbench()
  48. {
  49. rm -rf results/tracer-tbench*
  50. rm -rf $OUTFILE_TBENCH*.log
  51. rm -rf $OUTFILE_TBENCH*.result
  52. }
  53. # $1: governor, $2: loop
  54. run_tbench()
  55. {
  56. echo "Launching amd pstate tracer for $1 #$2 tracer_interval: $TRACER_INTERVAL"
  57. $TRACER -n tracer-tbench-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 &
  58. printf "Test tbench for $1 #$2 time_limit: $TIME_LIMIT procs_num: $PROCESS_NUM\n"
  59. tbench_srv > /dev/null 2>&1 &
  60. $PERF stat -a --per-socket -I 1000 -e power/energy-pkg/ tbench -t $TIME_LIMIT $PROCESS_NUM > $OUTFILE_TBENCH-perf-$1-$2.log 2>&1
  61. pid=`pidof tbench_srv`
  62. kill $pid
  63. for job in `jobs -p`
  64. do
  65. echo "Waiting for job id $job"
  66. wait $job
  67. done
  68. }
  69. # $1: governor, $2: loop
  70. parse_tbench()
  71. {
  72. awk '{print $5}' results/tracer-tbench-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_TBENCH-des-perf-$1-$2.log
  73. avg_des_perf=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_TBENCH-des-perf-$1-$2.log)
  74. printf "Tbench-$1-#$2 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_TBENCH.result
  75. awk '{print $7}' results/tracer-tbench-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_TBENCH-freq-$1-$2.log
  76. avg_freq=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_TBENCH-freq-$1-$2.log)
  77. printf "Tbench-$1-#$2 avg freq: $avg_freq\n" | tee -a $OUTFILE_TBENCH.result
  78. awk '{print $11}' results/tracer-tbench-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_TBENCH-load-$1-$2.log
  79. avg_load=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_TBENCH-load-$1-$2.log)
  80. printf "Tbench-$1-#$2 avg load: $avg_load\n" | tee -a $OUTFILE_TBENCH.result
  81. grep Throughput $OUTFILE_TBENCH-perf-$1-$2.log | awk '{print $2}' > $OUTFILE_TBENCH-throughput-$1-$2.log
  82. tp_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-throughput-$1-$2.log)
  83. printf "Tbench-$1-#$2 throughput(MB/s): $tp_sum\n" | tee -a $OUTFILE_TBENCH.result
  84. grep Joules $OUTFILE_TBENCH-perf-$1-$2.log | awk '{print $4}' > $OUTFILE_TBENCH-energy-$1-$2.log
  85. en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-energy-$1-$2.log)
  86. printf "Tbench-$1-#$2 power consumption(J): $en_sum\n" | tee -a $OUTFILE_TBENCH.result
  87. # Permance is throughput per second, denoted T/t, where T is throught rendered in t seconds.
  88. # It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J),
  89. # and t is time measured in seconds(s). This means that performance per watt becomes
  90. # T/t T/t T
  91. # --- = --- = ---
  92. # P E/t E
  93. # with unit given by MB per joule.
  94. ppw=`echo "scale=4;($TIME_LIMIT-1)*$tp_sum/$en_sum" | bc | awk '{printf "%.4f", $0}'`
  95. printf "Tbench-$1-#$2 performance per watt(MB/J): $ppw\n" | tee -a $OUTFILE_TBENCH.result
  96. printf "\n" | tee -a $OUTFILE_TBENCH.result
  97. driver_name=`echo $(scaling_name)`
  98. store_csv_tbench "$driver_name-$1" $2 $avg_des_perf $avg_freq $avg_load $tp_sum $en_sum $ppw
  99. }
  100. # $1: governor
  101. loop_tbench()
  102. {
  103. printf "\nTbench total test times is $LOOP_TIMES for $1\n\n"
  104. for i in `seq 1 $LOOP_TIMES`
  105. do
  106. run_tbench $1 $i
  107. parse_tbench $1 $i
  108. done
  109. }
  110. # $1: governor
  111. gather_tbench()
  112. {
  113. printf "Tbench test result for $1 (loops:$LOOP_TIMES)" | tee -a $OUTFILE_TBENCH.result
  114. printf "\n--------------------------------------------------\n" | tee -a $OUTFILE_TBENCH.result
  115. grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "avg des perf:" | awk '{print $NF}' > $OUTFILE_TBENCH-des-perf-$1.log
  116. avg_des_perf=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-des-perf-$1.log)
  117. printf "Tbench-$1 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_TBENCH.result
  118. grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "avg freq:" | awk '{print $NF}' > $OUTFILE_TBENCH-freq-$1.log
  119. avg_freq=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-freq-$1.log)
  120. printf "Tbench-$1 avg freq: $avg_freq\n" | tee -a $OUTFILE_TBENCH.result
  121. grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "avg load:" | awk '{print $NF}' > $OUTFILE_TBENCH-load-$1.log
  122. avg_load=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-load-$1.log)
  123. printf "Tbench-$1 avg load: $avg_load\n" | tee -a $OUTFILE_TBENCH.result
  124. grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "throughput(MB/s):" | awk '{print $NF}' > $OUTFILE_TBENCH-throughput-$1.log
  125. tp_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-throughput-$1.log)
  126. printf "Tbench-$1 total throughput(MB/s): $tp_sum\n" | tee -a $OUTFILE_TBENCH.result
  127. avg_tp=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-throughput-$1.log)
  128. printf "Tbench-$1 avg throughput(MB/s): $avg_tp\n" | tee -a $OUTFILE_TBENCH.result
  129. grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "power consumption(J):" | awk '{print $NF}' > $OUTFILE_TBENCH-energy-$1.log
  130. en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-energy-$1.log)
  131. printf "Tbench-$1 total power consumption(J): $en_sum\n" | tee -a $OUTFILE_TBENCH.result
  132. avg_en=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-energy-$1.log)
  133. printf "Tbench-$1 avg power consumption(J): $avg_en\n" | tee -a $OUTFILE_TBENCH.result
  134. # Permance is throughput per second, denoted T/t, where T is throught rendered in t seconds.
  135. # It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J),
  136. # and t is time measured in seconds(s). This means that performance per watt becomes
  137. # T/t T/t T
  138. # --- = --- = ---
  139. # P E/t E
  140. # with unit given by MB per joule.
  141. ppw=`echo "scale=4;($TIME_LIMIT-1)*$avg_tp/$avg_en" | bc | awk '{printf "%.4f", $0}'`
  142. printf "Tbench-$1 performance per watt(MB/J): $ppw\n" | tee -a $OUTFILE_TBENCH.result
  143. printf "\n" | tee -a $OUTFILE_TBENCH.result
  144. driver_name=`echo $(scaling_name)`
  145. store_csv_tbench "$driver_name-$1" "Average" $avg_des_perf $avg_freq $avg_load $avg_tp $avg_en $ppw
  146. }
  147. # $1: base scaling_driver $2: base governor $3: comparative scaling_driver $4: comparative governor
  148. __calc_comp_tbench()
  149. {
  150. base=`grep "$1-$2" $OUTFILE_TBENCH.csv | grep "Average"`
  151. comp=`grep "$3-$4" $OUTFILE_TBENCH.csv | grep "Average"`
  152. if [ -n "$base" -a -n "$comp" ]; then
  153. printf "\n==================================================\n" | tee -a $OUTFILE_TBENCH.result
  154. printf "Tbench comparison $1-$2 VS $3-$4" | tee -a $OUTFILE_TBENCH.result
  155. printf "\n==================================================\n" | tee -a $OUTFILE_TBENCH.result
  156. # get the base values
  157. des_perf_base=`echo "$base" | awk '{print $3}' | sed s/,//`
  158. freq_base=`echo "$base" | awk '{print $4}' | sed s/,//`
  159. load_base=`echo "$base" | awk '{print $5}' | sed s/,//`
  160. perf_base=`echo "$base" | awk '{print $6}' | sed s/,//`
  161. energy_base=`echo "$base" | awk '{print $7}' | sed s/,//`
  162. ppw_base=`echo "$base" | awk '{print $8}' | sed s/,//`
  163. # get the comparative values
  164. des_perf_comp=`echo "$comp" | awk '{print $3}' | sed s/,//`
  165. freq_comp=`echo "$comp" | awk '{print $4}' | sed s/,//`
  166. load_comp=`echo "$comp" | awk '{print $5}' | sed s/,//`
  167. perf_comp=`echo "$comp" | awk '{print $6}' | sed s/,//`
  168. energy_comp=`echo "$comp" | awk '{print $7}' | sed s/,//`
  169. ppw_comp=`echo "$comp" | awk '{print $8}' | sed s/,//`
  170. # compare the base and comp values
  171. des_perf_drop=`echo "scale=4;($des_perf_comp-$des_perf_base)*100/$des_perf_base" | bc | awk '{printf "%.4f", $0}'`
  172. printf "Tbench-$1 des perf base: $des_perf_base comprison: $des_perf_comp percent: $des_perf_drop\n" | tee -a $OUTFILE_TBENCH.result
  173. freq_drop=`echo "scale=4;($freq_comp-$freq_base)*100/$freq_base" | bc | awk '{printf "%.4f", $0}'`
  174. printf "Tbench-$1 freq base: $freq_base comprison: $freq_comp percent: $freq_drop\n" | tee -a $OUTFILE_TBENCH.result
  175. load_drop=`echo "scale=4;($load_comp-$load_base)*100/$load_base" | bc | awk '{printf "%.4f", $0}'`
  176. printf "Tbench-$1 load base: $load_base comprison: $load_comp percent: $load_drop\n" | tee -a $OUTFILE_TBENCH.result
  177. perf_drop=`echo "scale=4;($perf_comp-$perf_base)*100/$perf_base" | bc | awk '{printf "%.4f", $0}'`
  178. printf "Tbench-$1 perf base: $perf_base comprison: $perf_comp percent: $perf_drop\n" | tee -a $OUTFILE_TBENCH.result
  179. energy_drop=`echo "scale=4;($energy_comp-$energy_base)*100/$energy_base" | bc | awk '{printf "%.4f", $0}'`
  180. printf "Tbench-$1 energy base: $energy_base comprison: $energy_comp percent: $energy_drop\n" | tee -a $OUTFILE_TBENCH.result
  181. ppw_drop=`echo "scale=4;($ppw_comp-$ppw_base)*100/$ppw_base" | bc | awk '{printf "%.4f", $0}'`
  182. printf "Tbench-$1 performance per watt base: $ppw_base comprison: $ppw_comp percent: $ppw_drop\n" | tee -a $OUTFILE_TBENCH.result
  183. printf "\n" | tee -a $OUTFILE_TBENCH.result
  184. store_csv_tbench "$1-$2 VS $3-$4" "Comprison(%)" "$des_perf_drop" "$freq_drop" "$load_drop" "$perf_drop" "$energy_drop" "$ppw_drop"
  185. fi
  186. }
  187. # calculate the comparison(%)
  188. calc_comp_tbench()
  189. {
  190. # acpi-cpufreq-ondemand VS acpi-cpufreq-schedutil
  191. __calc_comp_tbench ${all_scaling_names[0]} ${tbench_governors[0]} ${all_scaling_names[0]} ${tbench_governors[1]}
  192. # amd-pstate-ondemand VS amd-pstate-schedutil
  193. __calc_comp_tbench ${all_scaling_names[1]} ${tbench_governors[0]} ${all_scaling_names[1]} ${tbench_governors[1]}
  194. # acpi-cpufreq-ondemand VS amd-pstate-ondemand
  195. __calc_comp_tbench ${all_scaling_names[0]} ${tbench_governors[0]} ${all_scaling_names[1]} ${tbench_governors[0]}
  196. # acpi-cpufreq-schedutil VS amd-pstate-schedutil
  197. __calc_comp_tbench ${all_scaling_names[0]} ${tbench_governors[1]} ${all_scaling_names[1]} ${tbench_governors[1]}
  198. }
  199. # $1: file_name, $2: title, $3: ylable, $4: column
  200. plot_png_tbench()
  201. {
  202. # all_scaling_names[1] all_scaling_names[0] flag
  203. # amd-pstate acpi-cpufreq
  204. # N N 0
  205. # N Y 1
  206. # Y N 2
  207. # Y Y 3
  208. ret=`grep -c "${all_scaling_names[1]}" $OUTFILE_TBENCH.csv`
  209. if [ $ret -eq 0 ]; then
  210. ret=`grep -c "${all_scaling_names[0]}" $OUTFILE_TBENCH.csv`
  211. if [ $ret -eq 0 ]; then
  212. flag=0
  213. else
  214. flag=1
  215. fi
  216. else
  217. ret=`grep -c "${all_scaling_names[0]}" $OUTFILE_TBENCH.csv`
  218. if [ $ret -eq 0 ]; then
  219. flag=2
  220. else
  221. flag=3
  222. fi
  223. fi
  224. gnuplot << EOF
  225. set term png
  226. set output "$1"
  227. set title "$2"
  228. set xlabel "Test Cycles (round)"
  229. set ylabel "$3"
  230. set grid
  231. set style data histogram
  232. set style fill solid 0.5 border
  233. set boxwidth 0.8
  234. if ($flag == 1) {
  235. plot \
  236. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${tbench_governors[0]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${tbench_governors[0]}", \
  237. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${tbench_governors[1]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${tbench_governors[1]}"
  238. } else {
  239. if ($flag == 2) {
  240. plot \
  241. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${tbench_governors[0]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${tbench_governors[0]}", \
  242. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${tbench_governors[1]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${tbench_governors[1]}"
  243. } else {
  244. if ($flag == 3 ) {
  245. plot \
  246. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${tbench_governors[0]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${tbench_governors[0]}", \
  247. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${tbench_governors[1]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${tbench_governors[1]}", \
  248. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${tbench_governors[0]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${tbench_governors[0]}", \
  249. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${tbench_governors[1]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${tbench_governors[1]}"
  250. }
  251. }
  252. }
  253. quit
  254. EOF
  255. }
  256. amd_pstate_tbench()
  257. {
  258. printf "\n---------------------------------------------\n"
  259. printf "*** Running tbench ***"
  260. printf "\n---------------------------------------------\n"
  261. pre_clear_tbench
  262. get_lines_csv_tbench "Governor"
  263. if [ $? -eq 0 ]; then
  264. # add titles and unit for csv file
  265. store_csv_tbench "Governor" "Round" "Des-perf" "Freq" "Load" "Performance" "Energy" "Performance Per Watt"
  266. store_csv_tbench "Unit" "" "" "GHz" "" "MB/s" "J" "MB/J"
  267. fi
  268. backup_governor
  269. for governor in ${tbench_governors[*]} ; do
  270. printf "\nSpecified governor is $governor\n\n"
  271. switch_governor $governor
  272. loop_tbench $governor
  273. gather_tbench $governor
  274. done
  275. restore_governor
  276. plot_png_tbench "tbench_perfromance.png" "Tbench Benchmark Performance" "Performance" 6
  277. plot_png_tbench "tbench_energy.png" "Tbench Benchmark Energy" "Energy (J)" 7
  278. plot_png_tbench "tbench_ppw.png" "Tbench Benchmark Performance Per Watt" "Performance Per Watt (MB/J)" 8
  279. calc_comp_tbench
  280. post_clear_tbench
  281. }