gitsource.sh 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. #!/bin/bash
  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
  5. # gitsource test.
  6. # 1) Download and tar gitsource codes.
  7. # 2) Run gitsource benchmark on specific governors, ondemand or schedutil.
  8. # 3) Run tbench benchmark comparative test on acpi-cpufreq kernel driver.
  9. # 4) Get desire performance, frequency, load by perf.
  10. # 5) Get power consumption and throughput by amd_pstate_trace.py.
  11. # 6) Get run time by /usr/bin/time.
  12. # 7) Analyse test results and save it in file selftest.gitsource.csv.
  13. #8) Plot png images about time, energy and performance per watt for each test.
  14. # protect against multiple inclusion
  15. if [ $FILE_GITSOURCE ]; then
  16. return 0
  17. else
  18. FILE_GITSOURCE=DONE
  19. fi
  20. git_name="git-2.15.1"
  21. git_tar="$git_name.tar.gz"
  22. gitsource_url="https://github.com/git/git/archive/refs/tags/v2.15.1.tar.gz"
  23. gitsource_governors=("ondemand" "schedutil")
  24. # $1: governor, $2: round, $3: des-perf, $4: freq, $5: load, $6: time $7: energy, $8: PPW
  25. store_csv_gitsource()
  26. {
  27. echo "$1, $2, $3, $4, $5, $6, $7, $8" | tee -a $OUTFILE_GIT.csv > /dev/null 2>&1
  28. }
  29. # clear some special lines
  30. clear_csv_gitsource()
  31. {
  32. if [ -f $OUTFILE_GIT.csv ]; then
  33. sed -i '/Comprison(%)/d' $OUTFILE_GIT.csv
  34. sed -i "/$(scaling_name)/d" $OUTFILE_GIT.csv
  35. fi
  36. }
  37. # find string $1 in file csv and get the number of lines
  38. get_lines_csv_gitsource()
  39. {
  40. if [ -f $OUTFILE_GIT.csv ]; then
  41. return `grep -c "$1" $OUTFILE_GIT.csv`
  42. else
  43. return 0
  44. fi
  45. }
  46. pre_clear_gitsource()
  47. {
  48. post_clear_gitsource
  49. rm -rf gitsource_*.png
  50. clear_csv_gitsource
  51. }
  52. post_clear_gitsource()
  53. {
  54. rm -rf results/tracer-gitsource*
  55. rm -rf $OUTFILE_GIT*.log
  56. rm -rf $OUTFILE_GIT*.result
  57. }
  58. install_gitsource()
  59. {
  60. if [ ! -d $SCRIPTDIR/$git_name ]; then
  61. pushd $(pwd) > /dev/null 2>&1
  62. cd $SCRIPTDIR
  63. printf "Download gitsource, please wait a moment ...\n\n"
  64. wget -O $git_tar $gitsource_url > /dev/null 2>&1
  65. printf "Tar gitsource ...\n\n"
  66. tar -xzf $git_tar
  67. popd > /dev/null 2>&1
  68. fi
  69. }
  70. # $1: governor, $2: loop
  71. run_gitsource()
  72. {
  73. echo "Launching amd pstate tracer for $1 #$2 tracer_interval: $TRACER_INTERVAL"
  74. $TRACER -n tracer-gitsource-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 &
  75. printf "Make and test gitsource for $1 #$2 make_cpus: $MAKE_CPUS\n"
  76. BACKUP_DIR=$(pwd)
  77. pushd $BACKUP_DIR > /dev/null 2>&1
  78. cd $SCRIPTDIR/$git_name
  79. $PERF stat -a --per-socket -I 1000 -e power/energy-pkg/ /usr/bin/time -o $BACKUP_DIR/$OUTFILE_GIT.time-gitsource-$1-$2.log make test -j$MAKE_CPUS > $BACKUP_DIR/$OUTFILE_GIT-perf-$1-$2.log 2>&1
  80. popd > /dev/null 2>&1
  81. for job in `jobs -p`
  82. do
  83. echo "Waiting for job id $job"
  84. wait $job
  85. done
  86. }
  87. # $1: governor, $2: loop
  88. parse_gitsource()
  89. {
  90. awk '{print $5}' results/tracer-gitsource-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_GIT-des-perf-$1-$2.log
  91. avg_des_perf=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_GIT-des-perf-$1-$2.log)
  92. printf "Gitsource-$1-#$2 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_GIT.result
  93. awk '{print $7}' results/tracer-gitsource-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_GIT-freq-$1-$2.log
  94. avg_freq=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_GIT-freq-$1-$2.log)
  95. printf "Gitsource-$1-#$2 avg freq: $avg_freq\n" | tee -a $OUTFILE_GIT.result
  96. awk '{print $11}' results/tracer-gitsource-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_GIT-load-$1-$2.log
  97. avg_load=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_GIT-load-$1-$2.log)
  98. printf "Gitsource-$1-#$2 avg load: $avg_load\n" | tee -a $OUTFILE_GIT.result
  99. grep user $OUTFILE_GIT.time-gitsource-$1-$2.log | awk '{print $1}' | sed -e 's/user//' > $OUTFILE_GIT-time-$1-$2.log
  100. time_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-time-$1-$2.log)
  101. printf "Gitsource-$1-#$2 user time(s): $time_sum\n" | tee -a $OUTFILE_GIT.result
  102. grep Joules $OUTFILE_GIT-perf-$1-$2.log | awk '{print $4}' > $OUTFILE_GIT-energy-$1-$2.log
  103. en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-energy-$1-$2.log)
  104. printf "Gitsource-$1-#$2 power consumption(J): $en_sum\n" | tee -a $OUTFILE_GIT.result
  105. # Permance is the number of run gitsource per second, denoted 1/t, where 1 is the number of run gitsource in t
  106. # seconds. It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J),
  107. # and t is time measured in seconds(s). This means that performance per watt becomes
  108. # 1/t 1/t 1
  109. # ----- = ----- = ---
  110. # P E/t E
  111. # with unit given by 1 per joule.
  112. ppw=`echo "scale=9;1/$en_sum" | bc | awk '{printf "%.9f", $0}'`
  113. printf "Gitsource-$1-#$2 performance per watt(1/J): $ppw\n" | tee -a $OUTFILE_GIT.result
  114. printf "\n" | tee -a $OUTFILE_GIT.result
  115. driver_name=`echo $(scaling_name)`
  116. store_csv_gitsource "$driver_name-$1" $2 $avg_des_perf $avg_freq $avg_load $time_sum $en_sum $ppw
  117. }
  118. # $1: governor
  119. loop_gitsource()
  120. {
  121. printf "\nGitsource total test times is $LOOP_TIMES for $1\n\n"
  122. for i in `seq 1 $LOOP_TIMES`
  123. do
  124. run_gitsource $1 $i
  125. parse_gitsource $1 $i
  126. done
  127. }
  128. # $1: governor
  129. gather_gitsource()
  130. {
  131. printf "Gitsource test result for $1 (loops:$LOOP_TIMES)" | tee -a $OUTFILE_GIT.result
  132. printf "\n--------------------------------------------------\n" | tee -a $OUTFILE_GIT.result
  133. grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "avg des perf:" | awk '{print $NF}' > $OUTFILE_GIT-des-perf-$1.log
  134. avg_des_perf=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-des-perf-$1.log)
  135. printf "Gitsource-$1 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_GIT.result
  136. grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "avg freq:" | awk '{print $NF}' > $OUTFILE_GIT-freq-$1.log
  137. avg_freq=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-freq-$1.log)
  138. printf "Gitsource-$1 avg freq: $avg_freq\n" | tee -a $OUTFILE_GIT.result
  139. grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "avg load:" | awk '{print $NF}' > $OUTFILE_GIT-load-$1.log
  140. avg_load=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-load-$1.log)
  141. printf "Gitsource-$1 avg load: $avg_load\n" | tee -a $OUTFILE_GIT.result
  142. grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "user time(s):" | awk '{print $NF}' > $OUTFILE_GIT-time-$1.log
  143. time_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-time-$1.log)
  144. printf "Gitsource-$1 total user time(s): $time_sum\n" | tee -a $OUTFILE_GIT.result
  145. avg_time=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-time-$1.log)
  146. printf "Gitsource-$1 avg user times(s): $avg_time\n" | tee -a $OUTFILE_GIT.result
  147. grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "power consumption(J):" | awk '{print $NF}' > $OUTFILE_GIT-energy-$1.log
  148. en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-energy-$1.log)
  149. printf "Gitsource-$1 total power consumption(J): $en_sum\n" | tee -a $OUTFILE_GIT.result
  150. avg_en=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-energy-$1.log)
  151. printf "Gitsource-$1 avg power consumption(J): $avg_en\n" | tee -a $OUTFILE_GIT.result
  152. # Permance is the number of run gitsource per second, denoted 1/t, where 1 is the number of run gitsource in t
  153. # seconds. It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J),
  154. # and t is time measured in seconds(s). This means that performance per watt becomes
  155. # 1/t 1/t 1
  156. # ----- = ----- = ---
  157. # P E/t E
  158. # with unit given by 1 per joule.
  159. ppw=`echo "scale=9;1/$avg_en" | bc | awk '{printf "%.9f", $0}'`
  160. printf "Gitsource-$1 performance per watt(1/J): $ppw\n" | tee -a $OUTFILE_GIT.result
  161. printf "\n" | tee -a $OUTFILE_GIT.result
  162. driver_name=`echo $(scaling_name)`
  163. store_csv_gitsource "$driver_name-$1" "Average" $avg_des_perf $avg_freq $avg_load $avg_time $avg_en $ppw
  164. }
  165. # $1: base scaling_driver $2: base governor $3: comparison scaling_driver $4: comparison governor
  166. __calc_comp_gitsource()
  167. {
  168. base=`grep "$1-$2" $OUTFILE_GIT.csv | grep "Average"`
  169. comp=`grep "$3-$4" $OUTFILE_GIT.csv | grep "Average"`
  170. if [ -n "$base" -a -n "$comp" ]; then
  171. printf "\n==================================================\n" | tee -a $OUTFILE_GIT.result
  172. printf "Gitsource comparison $1-$2 VS $3-$4" | tee -a $OUTFILE_GIT.result
  173. printf "\n==================================================\n" | tee -a $OUTFILE_GIT.result
  174. # get the base values
  175. des_perf_base=`echo "$base" | awk '{print $3}' | sed s/,//`
  176. freq_base=`echo "$base" | awk '{print $4}' | sed s/,//`
  177. load_base=`echo "$base" | awk '{print $5}' | sed s/,//`
  178. time_base=`echo "$base" | awk '{print $6}' | sed s/,//`
  179. energy_base=`echo "$base" | awk '{print $7}' | sed s/,//`
  180. ppw_base=`echo "$base" | awk '{print $8}' | sed s/,//`
  181. # get the comparison values
  182. des_perf_comp=`echo "$comp" | awk '{print $3}' | sed s/,//`
  183. freq_comp=`echo "$comp" | awk '{print $4}' | sed s/,//`
  184. load_comp=`echo "$comp" | awk '{print $5}' | sed s/,//`
  185. time_comp=`echo "$comp" | awk '{print $6}' | sed s/,//`
  186. energy_comp=`echo "$comp" | awk '{print $7}' | sed s/,//`
  187. ppw_comp=`echo "$comp" | awk '{print $8}' | sed s/,//`
  188. # compare the base and comp values
  189. des_perf_drop=`echo "scale=4;($des_perf_comp-$des_perf_base)*100/$des_perf_base" | bc | awk '{printf "%.4f", $0}'`
  190. printf "Gitsource-$1 des perf base: $des_perf_base comprison: $des_perf_comp percent: $des_perf_drop\n" | tee -a $OUTFILE_GIT.result
  191. freq_drop=`echo "scale=4;($freq_comp-$freq_base)*100/$freq_base" | bc | awk '{printf "%.4f", $0}'`
  192. printf "Gitsource-$1 freq base: $freq_base comprison: $freq_comp percent: $freq_drop\n" | tee -a $OUTFILE_GIT.result
  193. load_drop=`echo "scale=4;($load_comp-$load_base)*100/$load_base" | bc | awk '{printf "%.4f", $0}'`
  194. printf "Gitsource-$1 load base: $load_base comprison: $load_comp percent: $load_drop\n" | tee -a $OUTFILE_GIT.result
  195. time_drop=`echo "scale=4;($time_comp-$time_base)*100/$time_base" | bc | awk '{printf "%.4f", $0}'`
  196. printf "Gitsource-$1 time base: $time_base comprison: $time_comp percent: $time_drop\n" | tee -a $OUTFILE_GIT.result
  197. energy_drop=`echo "scale=4;($energy_comp-$energy_base)*100/$energy_base" | bc | awk '{printf "%.4f", $0}'`
  198. printf "Gitsource-$1 energy base: $energy_base comprison: $energy_comp percent: $energy_drop\n" | tee -a $OUTFILE_GIT.result
  199. ppw_drop=`echo "scale=4;($ppw_comp-$ppw_base)*100/$ppw_base" | bc | awk '{printf "%.4f", $0}'`
  200. printf "Gitsource-$1 performance per watt base: $ppw_base comprison: $ppw_comp percent: $ppw_drop\n" | tee -a $OUTFILE_GIT.result
  201. printf "\n" | tee -a $OUTFILE_GIT.result
  202. store_csv_gitsource "$1-$2 VS $3-$4" "Comprison(%)" "$des_perf_drop" "$freq_drop" "$load_drop" "$time_drop" "$energy_drop" "$ppw_drop"
  203. fi
  204. }
  205. # calculate the comparison(%)
  206. calc_comp_gitsource()
  207. {
  208. # acpi-cpufreq-ondemand VS acpi-cpufreq-schedutil
  209. __calc_comp_gitsource ${all_scaling_names[0]} ${gitsource_governors[0]} ${all_scaling_names[0]} ${gitsource_governors[1]}
  210. # amd-pstate-ondemand VS amd-pstate-schedutil
  211. __calc_comp_gitsource ${all_scaling_names[1]} ${gitsource_governors[0]} ${all_scaling_names[1]} ${gitsource_governors[1]}
  212. # acpi-cpufreq-ondemand VS amd-pstate-ondemand
  213. __calc_comp_gitsource ${all_scaling_names[0]} ${gitsource_governors[0]} ${all_scaling_names[1]} ${gitsource_governors[0]}
  214. # acpi-cpufreq-schedutil VS amd-pstate-schedutil
  215. __calc_comp_gitsource ${all_scaling_names[0]} ${gitsource_governors[1]} ${all_scaling_names[1]} ${gitsource_governors[1]}
  216. }
  217. # $1: file_name, $2: title, $3: ylable, $4: column
  218. plot_png_gitsource()
  219. {
  220. # all_scaling_names[1] all_scaling_names[0] flag
  221. # amd-pstate acpi-cpufreq
  222. # N N 0
  223. # N Y 1
  224. # Y N 2
  225. # Y Y 3
  226. ret=`grep -c "${all_scaling_names[1]}" $OUTFILE_GIT.csv`
  227. if [ $ret -eq 0 ]; then
  228. ret=`grep -c "${all_scaling_names[0]}" $OUTFILE_GIT.csv`
  229. if [ $ret -eq 0 ]; then
  230. flag=0
  231. else
  232. flag=1
  233. fi
  234. else
  235. ret=`grep -c "${all_scaling_names[0]}" $OUTFILE_GIT.csv`
  236. if [ $ret -eq 0 ]; then
  237. flag=2
  238. else
  239. flag=3
  240. fi
  241. fi
  242. gnuplot << EOF
  243. set term png
  244. set output "$1"
  245. set title "$2"
  246. set xlabel "Test Cycles (round)"
  247. set ylabel "$3"
  248. set grid
  249. set style data histogram
  250. set style fill solid 0.5 border
  251. set boxwidth 0.8
  252. if ($flag == 1) {
  253. plot \
  254. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${gitsource_governors[0]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${gitsource_governors[0]}", \
  255. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${gitsource_governors[1]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${gitsource_governors[1]}"
  256. } else {
  257. if ($flag == 2) {
  258. plot \
  259. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${gitsource_governors[0]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${gitsource_governors[0]}", \
  260. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${gitsource_governors[1]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${gitsource_governors[1]}"
  261. } else {
  262. if ($flag == 3 ) {
  263. plot \
  264. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${gitsource_governors[0]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${gitsource_governors[0]}", \
  265. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${gitsource_governors[1]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${gitsource_governors[1]}", \
  266. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${gitsource_governors[0]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${gitsource_governors[0]}", \
  267. "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${gitsource_governors[1]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${gitsource_governors[1]}"
  268. }
  269. }
  270. }
  271. quit
  272. EOF
  273. }
  274. amd_pstate_gitsource()
  275. {
  276. printf "\n---------------------------------------------\n"
  277. printf "*** Running gitsource ***"
  278. printf "\n---------------------------------------------\n"
  279. pre_clear_gitsource
  280. install_gitsource
  281. get_lines_csv_gitsource "Governor"
  282. if [ $? -eq 0 ]; then
  283. # add titles and unit for csv file
  284. store_csv_gitsource "Governor" "Round" "Des-perf" "Freq" "Load" "Time" "Energy" "Performance Per Watt"
  285. store_csv_gitsource "Unit" "" "" "GHz" "" "s" "J" "1/J"
  286. fi
  287. backup_governor
  288. for governor in ${gitsource_governors[*]} ; do
  289. printf "\nSpecified governor is $governor\n\n"
  290. switch_governor $governor
  291. loop_gitsource $governor
  292. gather_gitsource $governor
  293. done
  294. restore_governor
  295. plot_png_gitsource "gitsource_time.png" "Gitsource Benchmark Time" "Time (s)" 6
  296. plot_png_gitsource "gitsource_energy.png" "Gitsource Benchmark Energy" "Energy (J)" 7
  297. plot_png_gitsource "gitsource_ppw.png" "Gitsource Benchmark Performance Per Watt" "Performance Per Watt (1/J)" 8
  298. calc_comp_gitsource
  299. post_clear_gitsource
  300. }