contributed by <TempoJiJi
>
TempoJiJi
raytracing
sysprog21
SarahYuHanCheng
之前已對raytracing做過各方面的研究,但會做一次總復習,且會着重在上次未能達到的目標上。
過去的共筆:組別共筆, 個人共筆
測試未優化的程式效能:
利用gprof觀察程式效能及行爲,在Makefile的編譯選項裏加入 -pg ,再進行編譯跟執行,就會產生一個gmon.out檔:
這裏可以看到dot_product跟subtrace_vector是最花時間的地方,程式執行期間總共被呼叫了接近7前萬次(dot_product)。
優點:
缺點:
這裏可以看到利用迴圈來計算dot_product,而迴圈會有branch的情況發生,導致效能不好,所以就將迴圈拆開(loop unrolling):
可以看到只改一個dot_product時間就快了近0.4秒左右。
inline是向編譯器提出“建議”,把inline的函數在函數位置直接展開(減輕系統負擔(overhead)),編譯器會對比兩者執行時間後選擇執行inline與否。
優點:
在fucntion後面加上 __forceinline
編譯加上 -D__forceinline="attribute((always_inline))" 進行編譯:
時間比原本的快了0.2秒左右,接下來用gprof觀察function call:
可以看到math_tookit.h裏的function已經不見了
優點:
缺點:
將math_tookit.h裏的function改爲Macro來進行計算,這樣就能減少function call(stack frame的push,pop等行爲)所帶來的時間花費
這裏可以看到時間比loop unrolling快了近0.2秒左右,因此決定將math_tookit.h裏的花費較大的function都改爲Macro argument
根據gprof的結果,可以知道哪個function的花費最大,因此將它們都改爲Macro argument即可
可以看到只改了math_tookit.h整個程式的效能就快了接近1倍,可見程式的效能瓶頸真的是在math_tookit.h裏。
首先來實做OpenMP,在for迴圈上加上:
num_threads是要建立的執行緒數量。private可以確保變數在各個執行緒裏是獨立的,並不會因爲某個執行緒改變了變數,而影響到其它執行緒。
在raytracing的兩層for迴圈上加上:
這裏將stk、d、object_color設爲private,是因爲這3個的值是會在各個執行緒裏進行更動。
最後要記得 #include<omp.h> , 以及在編譯選項中加上 -fopenp
執行結果:
不同的num_thread比較圖:
當function的參數超過一個,在建立pthread的時候需要將所有參數打包起來,才能傳送給function:
將圖片分成不同的等份交給不同的執行緒去進行,這裏我會先將row分成4個等份,再用4個執行緒去執行:
執行結果:
不同thread數量的比較圖:
由上圖可得知,thread的數量越多,不代表程式效能越好。
合並所有方法,再跟不同的編譯優化做對比: