# 2018q3 Homework3 (dict) contributed by < [`p61402`](https://github.com/p61402) > ###### tags: `sysprog` ## 視覺化效能分析 ### 觀察`script`資料夾中的`.gp`檔 - `runtime.gp`:看起來需要`output.txt`來繪圖 ```gnuplot= reset set ylabel 'time(sec)' set style fill solid set key center top set title 'perfomance comparison' set term png enhanced font 'Verdana,10' set output 'runtime.png' plot [:][y=0:0.250]'output.txt' using 2:xtic(1) with histogram title 'cpy', \ '' using 3:xtic(1) with histogram title 'ref' , \ '' using ($0-0.500):(0.110):2 with labels title ' ' textcolor lt 1, \ '' using ($0-0.500):(0.120):3 with labels title ' ' textcolor lt 2, ``` - `runtime3.gp`:需要`bench_cpy.txt` ```guuplot= reset set xlabel 'prefix' set ylabel 'time(sec)' set title 'perfomance comparison' set term png enhanced font 'Verdana,10' set output 'runtime3.png' set format x "%10.0f" set xtic 1200 set xtics rotate by 45 right plot [:12500][:1000]'bench_cpy.txt' using 1:2 with points title 'cpy',\ ``` - `runtimebox.gp`:顯示一些統計的數據 ```gnuplot= stats "bench_ref.txt" using 2 stats "bench_cpy.txt" using 2 ``` - `runtimept.gp`:使用`bench_cpy.txt` ```gnuplot= reset set xlabel 'prefix' set ylabel 'time(sec)' set title 'perfomance comparison' set term png enhanced font 'Verdana,10' set output 'runtime2.png' set format x "%10.0f" set xtic 1200 set xtics rotate by 45 right plot [:12500][:1000]'bench_cpy.txt' using 1:2 with points title 'cpy',\ 'bench_ref.txt' using 1:2 with points title 'ref',\ ``` 個人覺得檔名取得有些不知所以然,讓人不太能夠理解用處如何。 無論如何,看起來需要以上三個檔案來進行繪圖。 首先是`bench_ref.txt`以及`bench_cpy.txt`,比對`test_ref.c`以及`test_cpy.c`發現前者相對於後者少了下列這一段程式碼: ```c= if (argc == 2 && strcmp(argv[1], "--bench") == 0) { int stat = bench_test(root, BENCH_TEST_FILE, LMAX); tst_free_all(root); return stat; } FILE *output; output = fopen("cpy.txt", "a"); if (output != NULL) { fprintf(output, "%.6f\n", t2 - t1); fclose(output); } else printf("open file error\n"); ``` 因此稍微改動一下將以下程式碼加入`test_ref.c`: ```c= if (argc == 2 && strcmp(argv[1], "--bench") == 0) { int stat = bench_test(root, BENCH_TEST_FILE, LMAX); tst_free(root); return stat; } FILE *output; output = fopen("ref.txt", "a"); if (output != NULL) { fprintf(output, "%.6f\n", t2 - t1); fclose(output); } else printf("open file error\n"); ``` ### Makefile 改動 `output.txt`由`calculate.c`產生,而`calculate.c`需要`ref.txt`以及`cpy.txt`這兩個檔案,這兩個檔案由`test_ref.c`及`test_cpy.c`產生。 `test`的部分可以對`cpy`以及`ref`兩種方法執行 100 次的過程進行效能分析: ```makefile test: $(TESTS) echo 3 | sudo tee /proc/sys/vm/drop_caches; perf stat --repeat 100 \ -e cache-misses,cache-references,instructions,cycles \ ./test_cpy --bench $(TEST_DATA) perf stat --repeat 100 \ -e cache-misses,cache-references,instructions,cycles \ ./test_ref --bench $(TEST_DATA) ``` `$ make test` 後出現以下錯誤: ```bash Error: You may not have permission to collect stats. Consider tweaking /proc/sys/kernel/perf_event_paranoid, which controls use of the performance events system by unprivileged users (without CAP_SYS_ADMIN). The current value is 3: -1: Allow use of (almost) all events by all users Ignore mlock limit after perf_event_mlock_kb without CAP_IPC_LOCK >= 0: Disallow ftrace function tracepoint by users without CAP_SYS_ADMIN Disallow raw tracepoint access by users without CAP_SYS_ADMIN >= 1: Disallow CPU event access by users without CAP_SYS_ADMIN >= 2: Disallow kernel profiling by users without CAP_SYS_ADMIN To make this setting permanent, edit /etc/sysctl.conf too, e.g.: kernel.perf_event_paranoid = -1 ``` 看一下目前的權限: ```bash $ cat /proc/sys/kernel/perf_event_paranoid 3 ``` 表示`perf`沒有權限可以執行,直接權限全開設為`-1`了: ```bash $ sudo sh -c " echo -1 > /proc/sys/kernel/perf_event_paranoid" ``` 成功權限全開: ```bash $ cat /proc/sys/kernel/perf_event_paranoid -1 ``` 將程式碼中冗余的`printf`註解掉後,重新`$ make test`後得到以下結果: ```bash Performance counter stats for './test_cpy --bench s Tai' (100 runs): 1,021,598 cache-misses # 44.429 % of all cache refs ( +- 0.15% ) 2,299,368 cache-references ( +- 0.13% ) 535,940,231 instructions # 1.17 insn per cycle ( +- 0.00% ) 457,889,685 cycles ( +- 0.15% ) 0.159220105 seconds time elapsed ( +- 0.23% ) Performance counter stats for './test_ref --bench s Tai' (100 runs): 1,227,952 cache-misses # 43.083 % of all cache refs ( +- 0.42% ) 2,850,183 cache-references ( +- 0.23% ) 596,890,922 instructions # 1.07 insn per cycle ( +- 0.00% ) 557,316,632 cycles ( +- 0.16% ) 0.194107229 seconds time elapsed ( +- 0.25% ) ``` 仔細觀察程式碼就會發現,`test_ref.c`有使用 bloom filter,而`test_cpy.c`則無,減少了 cache miss 的次數,bloom filter 果然有奇效! 在此成功產生了`ref.txt`以及`cpy.txt`兩個檔案。 而`calculate.c`在`Makefile`中沒有進行編譯,看來得自己加了: ```makefile cal: calculate.c gcc -o calculate calculate.c ./calculate ``` 真是太讚了,成功產生`output.txt`檔。 至於`bench_cpy.txt`以及`bench_ref.txt`也是由`test_cpy.c`以及`test_ref.c`的這段程式碼產生: ```c= if (argc == 2 && strcmp(argv[1], "--bench") == 0) { int stat = bench_test(root, BENCH_TEST_FILE, LMAX); tst_free_all(root); return stat; } ``` 因此在`Makefile`定義兩個參數的執行: ```makefile one_test: test_cpy test_ref ./test_cpy --bench ./test_ref --bench ``` 接著再加入繪圖功能: ```makefile plot: one_test bench_cpy.txt bench_ref.txt output.txt $(Q)gnuplot scripts/runtime.gp $(Q)gnuplot scripts/runtime3.gp $(Q)gnuplot scripts/runtimept.gp $(Q)gnuplot scripts/runtimebox.gp ``` 輸入指令`$ make plot`,感動的一刻終於到了,成功產生出三張圖片! 在`.gp`檔中稍微修改了一下輸出的檔名,不然我真的會搞不清楚到底每張圖的用處是什麼: - `runtime.png` ![](https://i.imgur.com/GUKgk90.png) - `cpy.png` ![](https://i.imgur.com/hFt6JWw.png) - `compare.png` ![](https://i.imgur.com/8RXpe1C.png)