CUDA优化心得之测时函数设计

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/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/23057064/viewspace-662071/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值