CUDA優化心得之測時函式設計

yyfn風辰發表於2010-05-06
CUDA程式優化心得之測時函式的設計

近一年來,學習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;//列印出時間差
        };

子類秒計時器程式碼如下:

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);
                        }
        };

子類毫秒計時器程式碼如下:

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);
                        }
        };

子類微秒計時器程式碼如下:

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

這 種設計使得我們可以宣告一個計時器父類引用,而讓其實際指向子類,這樣,如果精度小了的話,就可以只更改一處,而不用更改其它的內容了。在我的實踐中,這 種基於物件的多型設計的計時器工作得很好。在開始計時處呼叫start方法,在計時終點呼叫stop方法,呼叫getTimeDiff方法返回經過的時間 數,但是這個方法有個問題就是如果兩個不同的子類的計時器,其用此函式獲得的值不能直接相加減,由於這個問題我本來想將其設定private,但是最終還 是讓其保持public,因為這符合C/C++的設計思想:程式設計師是最聰明的,他們應當知道會發生什麼,一切由他們來決定。函式 printTimeDiff列印計時時間。
        如果有一天C語言的clock函式精度達到了微秒,我們只用將包圍MicrosecondCounter類的條件編譯語句去掉就行了。如果有一天其精度達到了納秒,我們只用再寫一個類繼承TimeCounter類就行了,不用改寫任何程式碼。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23057064/viewspace-662071/,如需轉載,請註明出處,否則將追究法律責任。

相關文章