CUDA優化心得之測時函式設計
CUDA程式優化心得之測時函式的設計
近一年來,學習CUDA也算是有苦有甜,苦的是遇到問題時的無助、苦惱和迷茫,甜的是問題解決時的興奮,今天就利用這五一的假期把自己的經驗結合CUDA優化的內容寫下來,希望對於那些依舊在其中掙扎的同學有所幫助。
一、 測時
判斷程式優劣的最簡單方式就是計算程式的執行時間,在同一臺機器上,執行時間短的程式一般來說是更優的,當然不能一概而論,畢竟決定程式執行速度的因素很多,比如演算法,機器的指令集,使用的語言等等。
我們的目的是要設計一個既能夠在windows上執行,又能夠在linux上執行,既可以用於C,又可以用於CUDA的計時器,同時最好便於擴充套件。計時的 方法很多,如標準C庫的time、clock系列函式,CUDA的事件,linux下的gettimeofday,windows下的 GetTickCount。
本計時器系列採用C++的物件導向設計方法,基本的思路是設計一個父類,然後再從父類創造子類。這樣要建造一個新計時器,只要繼承父類就行了。
父類程式碼如下:
子類秒計時器程式碼如下:
子類毫秒計時器程式碼如下:
子類微秒計時器程式碼如下:
這 種設計使得我們可以宣告一個計時器父類引用,而讓其實際指向子類,這樣,如果精度小了的話,就可以只更改一處,而不用更改其它的內容了。在我的實踐中,這 種基於物件的多型設計的計時器工作得很好。在開始計時處呼叫start方法,在計時終點呼叫stop方法,呼叫getTimeDiff方法返回經過的時間 數,但是這個方法有個問題就是如果兩個不同的子類的計時器,其用此函式獲得的值不能直接相加減,由於這個問題我本來想將其設定private,但是最終還 是讓其保持public,因為這符合C/C++的設計思想:程式設計師是最聰明的,他們應當知道會發生什麼,一切由他們來決定。函式 printTimeDiff列印計時時間。
如果有一天C語言的clock函式精度達到了微秒,我們只用將包圍MicrosecondCounter類的條件編譯語句去掉就行了。如果有一天其精度達到了納秒,我們只用再寫一個類繼承TimeCounter類就行了,不用改寫任何程式碼。
近一年來,學習CUDA也算是有苦有甜,苦的是遇到問題時的無助、苦惱和迷茫,甜的是問題解決時的興奮,今天就利用這五一的假期把自己的經驗結合CUDA優化的內容寫下來,希望對於那些依舊在其中掙扎的同學有所幫助。
一、 測時
判斷程式優劣的最簡單方式就是計算程式的執行時間,在同一臺機器上,執行時間短的程式一般來說是更優的,當然不能一概而論,畢竟決定程式執行速度的因素很多,比如演算法,機器的指令集,使用的語言等等。
我們的目的是要設計一個既能夠在windows上執行,又能夠在linux上執行,既可以用於C,又可以用於CUDA的計時器,同時最好便於擴充套件。計時的 方法很多,如標準C庫的time、clock系列函式,CUDA的事件,linux下的gettimeofday,windows下的 GetTickCount。
本計時器系列採用C++的物件導向設計方法,基本的思路是設計一個父類,然後再從父類創造子類。這樣要建造一個新計時器,只要繼承父類就行了。
父類程式碼如下:
CODE:
class TimeCounter{
protected :
clock_t startp,endp;
public :
TimeCounter():startp(-1),endp(-1){}
void start(){//設定計時起點
#ifdef __CUDACC__
cudaThreadSynchronize();
#endif
startp=clock();
}
void stop(){//設定計時終點
if(-1==startp){
perror("you must set start point at first");
}else{
#ifdef __CUDACC__
cudaThreadSynchronize();
#endif
endp=clock();
}
}
virtual long getTimeDiff()=0;//返回時間差滴答數
virtual void printTimeDiff()=0;//列印出時間差
};
protected :
clock_t startp,endp;
public :
TimeCounter():startp(-1),endp(-1){}
void start(){//設定計時起點
#ifdef __CUDACC__
cudaThreadSynchronize();
#endif
startp=clock();
}
void stop(){//設定計時終點
if(-1==startp){
perror("you must set start point at first");
}else{
#ifdef __CUDACC__
cudaThreadSynchronize();
#endif
endp=clock();
}
}
virtual long getTimeDiff()=0;//返回時間差滴答數
virtual void printTimeDiff()=0;//列印出時間差
};
子類秒計時器程式碼如下:
CODE:
class SecondCounter:public TimeCounter{
public :
long getTimeDiff(){
if(-1==endp){
perror("you must set stop point before invoke this function");
exit(1);
}else{
return (endp-startp)/CLOCKS_PER_SEC;
}
}
void printTimeDiff(){
long temp=getTimeDiff();
printf("use time :%lds\n",temp);
}
};
public :
long getTimeDiff(){
if(-1==endp){
perror("you must set stop point before invoke this function");
exit(1);
}else{
return (endp-startp)/CLOCKS_PER_SEC;
}
}
void printTimeDiff(){
long temp=getTimeDiff();
printf("use time :%lds\n",temp);
}
};
子類毫秒計時器程式碼如下:
CODE:
class MillisecondCounter:public TimeCounter{
public :
long getTimeDiff(){
if(-1==endp){
perror("you must set stop point before invoke this function");
exit(1);
}else{
return 1.0f*(endp-startp)/CLOCKS_PER_SEC*1000;
}
}
void printTimeDiff(){
long temp=getTimeDiff();
printf("use time :%ldms\n",temp);
}
};
public :
long getTimeDiff(){
if(-1==endp){
perror("you must set stop point before invoke this function");
exit(1);
}else{
return 1.0f*(endp-startp)/CLOCKS_PER_SEC*1000;
}
}
void printTimeDiff(){
long temp=getTimeDiff();
printf("use time :%ldms\n",temp);
}
};
子類微秒計時器程式碼如下:
CODE:
#ifdef __CUDACC__
class MicrosecondCounter:public TimeCounter{
public:
long getTimeDiff(){
if(-1==endp){
printf("please set start point or end point\n");
exit(1);
}else{
return 1.0f*(endp-startp)/CLOCKS_PER_SEC*1000000;
}
}
void printTimeDiff(){
long temp=getTimeDiff();
printf("use time:%ld us\n",temp);
}
};
#endif
class MicrosecondCounter:public TimeCounter{
public:
long getTimeDiff(){
if(-1==endp){
printf("please set start point or end point\n");
exit(1);
}else{
return 1.0f*(endp-startp)/CLOCKS_PER_SEC*1000000;
}
}
void printTimeDiff(){
long temp=getTimeDiff();
printf("use time:%ld us\n",temp);
}
};
#endif
這 種設計使得我們可以宣告一個計時器父類引用,而讓其實際指向子類,這樣,如果精度小了的話,就可以只更改一處,而不用更改其它的內容了。在我的實踐中,這 種基於物件的多型設計的計時器工作得很好。在開始計時處呼叫start方法,在計時終點呼叫stop方法,呼叫getTimeDiff方法返回經過的時間 數,但是這個方法有個問題就是如果兩個不同的子類的計時器,其用此函式獲得的值不能直接相加減,由於這個問題我本來想將其設定private,但是最終還 是讓其保持public,因為這符合C/C++的設計思想:程式設計師是最聰明的,他們應當知道會發生什麼,一切由他們來決定。函式 printTimeDiff列印計時時間。
如果有一天C語言的clock函式精度達到了微秒,我們只用將包圍MicrosecondCounter類的條件編譯語句去掉就行了。如果有一天其精度達到了納秒,我們只用再寫一個類繼承TimeCounter類就行了,不用改寫任何程式碼。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23057064/viewspace-662071/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- python效能優化之函式執行時間分析Python優化函式
- 效能優化之節流函式---throttle優化函式
- Excel 優化函式Excel優化函式
- MySQL效能優化之索引設計MySql優化索引
- 函式設計函式
- MySQL函式索引及優化MySql函式索引優化
- React函式式元件的效能優化React函式元件優化
- python之為函式執行設定超時時間(允許函式執行的最大時間)Python函式
- PHP函式漏洞審計之addslashes函式-PHP函式
- Golang時間函式及測試函式執行時間案例Golang函式
- 函式程式設計函式程式設計
- JavaScript函數語言程式設計(純函式、柯里化以及組合函式)JavaScript函數程式設計函式
- 設計模式基礎 之 4 高階函式設計模式函式
- python程式設計之slice與indices函式用法Python程式設計函式
- 如何使用函式來優化效能函式優化
- 程式設計優化之管道資料流程式設計優化
- 好程式設計師Python培訓分享函數語言程式設計之匿名函式程式設計師Python函數函式
- 測開之函式進階· 第2篇《純函式》函式
- 測開之函式進階· 第4篇《匿名函式》函式
- 測開之函式進階· 第5篇《偏函式》函式
- JavaScript函數語言程式設計之pointfree與宣告式程式設計JavaScript函數程式設計
- JavaScript函數語言程式設計,真香之組合函式(二)JavaScript函數程式設計函式
- JavaScript函數語言程式設計之深入理解純函式JavaScript函數程式設計函式
- 03 shell程式設計之case語句與函式程式設計函式
- 程式設計心得程式設計
- 用函式實現模組化程式設計二函式程式設計
- 用函式實現模組化程式設計三函式程式設計
- 用函式實現模組化程式設計一函式程式設計
- 前端優化常用技術心得前端優化
- 資料庫優化之臨時表優化資料庫優化
- 理解並優化函式節流Throttle優化函式
- 函式呼叫的代價與優化函式優化
- [JS效能優化]函式去抖(debounce)與函式節流(throttle)JS優化函式
- 測開之函式進階· 第1篇《遞迴函式》函式遞迴
- javascript設計模式第三章分時函式JavaScript設計模式函式
- JavaScript 設計模式系列 – 自定義函式(惰性函式)JavaScript設計模式函式
- 前端之函式柯里化Currying前端函式
- python函數語言程式設計之yield表示式形式Python函數程式設計
- python函式程式設計 返回函式 匿名函式 裝飾器 偏函式Python函式程式設計