TempoJiJi
功能:了解各函式消耗的時間,及各函式互相調用的關係
使用:
編譯和連結時加上-pg
參數
執行,透過 gprof 分析產生的 profiling 資料 (查看有無 gmon.out
檔案產生)
gprof -b raytracing gmon.out | less
less
讓我們可以用上下鍵查看分析結果
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
24.31 0.86 0.86 69646433 0.00 0.00 dot_product
20.92 1.60 0.74 56956357 0.00 0.00 subtract_vector
欄位說明:
%time
:某函式的執行時間佔全部的百分比cumulative seconds
: 累計執行時間self seconds
: 執行過程中,函式的執行時間calls
: 執行過程中,函式被呼叫的次數self ms/call
: 每次被呼叫時 平均花費了多少milliseconds執行函式total ms/call
: 每次被呼叫時,平均花費了多milliseconds執行函式和函式中呼叫的routine Call graph
granularity: each sample hit covers 2 byte(s) for 0.28% of 3.54 seconds
index % time self children called name
0.01 3.53 1/1 main [2]
[1] 100.0 0.01 3.53 1 raytracing [1]
0.05 3.34 1048576/1048576 ray_color [3]
0.05 0.10 1048576/1048576 rayConstruction [15]
0.00 0.00 1/1 calculateBasisVectors [22]
0.00 0.00 1048576/1048576 idx_stack_init [26]
分項解說:
children
:函式中呼叫的subroutine的執行時間called
: 函式被呼叫的次數,如果是遞迴呼叫,會有兩個數字,第二個數字表示遞迴呼叫的次數
children
: 函式呼叫其它subroutine的執行時間self
+ children
的總合等於函式被 main()
呼叫後的實際執行時間called
: 兩個數字,第一個代表函式被main()呼叫的次數,第二個數字代表被所有caller functions(程式可能也會有其它function呼叫)呼叫的次數Perf: 統計程式在執行過程中的事件
Gprof: 記錄呼叫次數等資訊
三維電腦圖形學中的特殊描繪 (rendering) 演算法,跟蹤從眼睛發出的光線而不是光源發出的光線,對於反射與折射有更準確的模擬效果
打開程式碼,依照作業說明上的指示 make PORFILE=1
-pg:是使用Gropf要加的指令
cc -std=gnu99 -Wall -O0 -g -pg -c -o objects.o objects.c
cc -std=gnu99 -Wall -O0 -g -pg -c -o raytracing.o raytracing.c
cc -std=gnu99 -Wall -O0 -g -pg -c -o main.o main.c
cc -o raytracing objects.o raytracing.o main.o -lm -pg
ifeq ($(strip $(PROFILE)),1)
PROF_FLAGS = -pg
CFLAGS += $(PROF_FLAGS)
LDFLAGS += $(PROF_FLAGS)
endif
再翻起makefile語法
執行結果:
# Rendering scene
Done!
Execution time of raytracing() : 5.608881 sec
gprof -b raytracing gmon.out | less
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
27.53 0.93 0.93 69646433 0.00 0.00 dot_product
17.17 1.51 0.58 56956357 0.00 0.00 subtract_vector
9.18 1.82 0.31 13861875 0.00 0.00 rayRectangularIntersection
7.70 2.08 0.26 31410180 0.00 0.00 multiply_vector
6.81 2.31 0.23 17836094 0.00 0.00 add_vector
6.51 2.53 0.22 10598450 0.00 0.00 normalize
6.22 2.74 0.21 13861875 0.00 0.00 raySphereIntersection
5.33 2.92 0.18 17821809 0.00 0.00 cross_product
3.85 3.05 0.13 4620625 0.00 0.00 ray_hit_object
2.07 3.12 0.07 3838091 0.00 0.00 length
1.78 3.18 0.06 4221152 0.00 0.00 multiply_vectors
1.78 3.24 0.06 1048576 0.00 0.00 ray_color
static inline
inline
: 提醒compiler可以將function本體直接展開到呼叫該function的位置,而不需要原本的 function prologue / epilogue
loop unrolling
OpenMP
-fopenmp
# Rendering scene
Done!
Execution time of raytracing() : 4.754009 sec
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
28.21 0.75 0.75 69646433 0.00 0.00 dot_product
13.92 1.12 0.37 10598450 0.00 0.00 normalize
11.29 1.42 0.30 13861875 0.00 0.00 raySphereIntersection
7.90 1.63 0.21 56956357 0.00 0.00 subtract_vector
7.90 1.84 0.21 13861875 0.00 0.00 rayRectangularIntersection
7.52 2.04 0.20 17821809 0.00 0.00 cross_product
4.14 2.15 0.11 31410180 0.00 0.00 multiply_vector
3.39 2.24 0.09 17836094 0.00 0.00 add_vector
3.01 2.32 0.08 4620625 0.00 0.00 ray_hit_object
3.01 2.40 0.08 1048576 0.00 0.00 ray_color
1.50 2.44 0.04 2110576 0.00 0.00 compute_specular_diffuse
1.50 2.48 0.04 1048576 0.00 0.00 rayConstruction
看到詹欣達學長的筆記後決定試一試
決定inline function是否執行是由compiler決定,但經過搜尋後發現有兩個類型是inline function不會執行的,其中之一是要該函式不return任何值,而math_toolkit.h要回傳值的有dot_product() length()和scalar_triple()
方法:針對上面3個函式和cross_product(scalar_triple()有用到),加入inline __attribute__((always_inline))
結果:
# Rendering scene
Done!
Execution time of raytracing() : 4.552191 sec
# Rendering scene
Done!
Execution time of raytracing() : 3.290624 sec
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
34.49 0.10 0.10 386260 0.00 0.00 rayRectangularIntersection
34.49 0.20 0.10 367224 0.00 0.00 raySphereIntersection
10.35 0.23 0.03 29896 0.00 0.01 ray_color
6.90 0.25 0.02 55505 0.00 0.00 compute_specular_diffuse
3.45 0.26 0.01 133214 0.00 0.00 ray_hit_object
3.45 0.27 0.01 66535 0.00 0.00 localColor
3.45 0.28 0.01 35712 0.00 0.00 refraction
3.45 0.29 0.01 29303 0.00 0.00 rayConstruction
0.00 0.29 0.00 74444 0.00 0.00 idx_stack_empty
0.00 0.29 0.00 69735 0.00 0.00 idx_stack_top
0.00 0.29 0.00 38372 0.00 0.00 reflection
0.00 0.29 0.00 36207 0.00 0.00 idx_stack_push
-fopenmp
,LDFLAGS加上-lgomp
#pragma omp parallel for collapse(3)
error: not enough perfectly nested loops before ‘double’
double r = 0, g = 0, b = 0;
修改:看了詹欣達學長的筆記,在前面加上#pragma omp parallel for num_threads(64) private(d),private(object_color),private(stk)
順利編譯過了
private:
64個threads結果:
# Rendering scene
Done!
Execution time of raytracing() : 1.370892 sec
還要再多看看資料~研究一下collapse private
==>從上面列舉的threads數來看,threads愈多執行的時間雖然愈短,但時間下降的幅度也愈小。
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
46.36 0.19 0.19 761781 0.00 0.00 rayRectangularIntersection
17.08 0.26 0.07 129903 0.00 0.00 localColor
14.64 0.32 0.06 745257 0.00 0.00 raySphereIntersection
9.76 0.36 0.04 264403 0.00 0.00 ray_hit_object
4.88 0.38 0.02 115772 0.00 0.00 compute_specular_diffuse
4.88 0.40 0.02 49185 0.00 0.01 ray_color
2.44 0.41 0.01 77232 0.00 0.00 reflection
0.00 0.41 0.00 164302 0.00 0.00 idx_stack_empty
0.00 0.41 0.00 147711 0.00 0.00 idx_stack_top
0.00 0.41 0.00 77722 0.00 0.00 refraction
0.00 0.41 0.00 73367 0.00 0.00 idx_stack_push
0.00 0.41 0.00 70649 0.00 0.00 protect_color_overflow
誠實面對:我跟threads不熟!!
好好學習並實作!!
參考下方學長hackpad,也把thread用在function raytracing()中
pthread_create()
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
由於pthread_create(),function傳進的參數只能有一個,因此把原本raytracing()的參數打包成一個structure
system embedded
HW1-2