contributed by <Jim00000
>
awesome face
☺
從參考資料3中大概可以得知gprof可以讓你知道程式把時間花在甚麼地方和哪個函式的呼叫了哪個函式並找出效能的瓶頸
參考參考資料3的資料做整理
在gcc的Options要加入 -pg,不然不會有call-graph data
-static-libgcc或是-static 在使用shared library時要加進去,不然會有segmentation fault
gcc -g -pg -static-libgcc ...
執行程式後產生一個含有profile data gmon.out的文件
gprof options executable-file gmon.out bb-data [yet-more-profile-data-files...] [> outfile]
或是簡單點
gprof executable-file gmon.out [> outfile]
其中options有可以
gprof -b -l a.out gmon.out > outfile
gprof -l -A -x a.out gmon.out > outfile
Q:How do I find which lines in my program were executed the most times?
A:Use the gcov program.
From answers to Common Questions,參考資料3
因為文件有提到gcov,那就來學習gcov吧,觀看參考資料5的文件
以參考資料5的資料做整理
gcov可以協助分析
gcc -fprofile-arcs -ftest-coverage source-file
執行程式後產生 source-file.gcda
gcov source-file.gcda
產生source-file.c.gcov檔案
使用 -b 來察看branch
gcov -b source-file
使用perf尋找熱點
./raytracing & perf top -p $!
Overhead為紅字部份的像是dot_product、subtract_vector、multiplt_vector、normalize與add_vector為math-toolkit.h裡的函式,消耗有一定程度cycles
而rayRectangularIntersection與raySphereIntersection則是raytracing.c內的函式,仔細瞧瞧原始碼裡的內容,在rayRectangularIntersection中大量使用subtract_vector、cross_product、dot_product、multiply_vector等toolkit.h內的數學函式而raySphereIntersection亦是如此,應此若能改良toolkit.h的函式,效能定有改善
再來是分析函式的使用頻率
make PROFILE=1
./raytracing
gprof -l -b raytracing gmon.out > report
打開report,節錄並重新排列米黃色字部份內容如下:
在call graph中,呼叫最多次數的函式為dot_product,緊接著是subtract_vector,除了rayRectangularIntersection與raySphereIntersection外,幾乎都是toolkit.h內的函式,因此,toolkit.h內的數學函式為改進效能的關鍵
再來比較每一行的執行數
gcov raytracing.gcda
可以觀察到執行次數最多的地方是for迴圈,所以,for迴圈是一個效能改善的重點,作業有提到loop unrolling的技巧
將loop unrolling後的math-toolkit.h內的for loop展開後的執行結果如下
使用OpenMP修改RayTracing程式,參考OpenMP文件(參考資料7)
在raytracing.c的文件中找到一處適合修改成多執行續的地方
這裡可以變成多執行續處理,但是要考慮各個資料相依性與獨立性,這裡卡了一段時間,參考同學的hackmd(參考資料8)後找出必須獨立的資料(或是說每個執性緒都有各自的資料副本而非共享資料)為d,stk與object_color,才讓輸出的圖形是正確的。
測試過部份loop的schedule方法(意指迴圈是如何被分配或切割到各個執行緒,來參考資料7中對schedule的解釋),dynamic的效率是比較好的