在C++中,经常需要通过计时来统计性能信息,通过统计的耗时信息,来分析性能瓶颈,通常情况下,可能毫秒级别的时间统计就足够用了,但是在毫厘必争的性能热点的地方,毫秒级别的统计还是不够的,这种情况下,就需要至少微秒级别的统计信息,甚至要精确到CPU的指令周期级别。下面来重点说一下毫秒级的计时统计信息。

毫厘必争--微秒计时思路

在Windows平台上,用来统计微秒级别耗时信息,需要用到两个Windows API:

BOOL WINAPI QueryPerformanceFrequency(
  _Out_  LARGE_INTEGER *lpFrequency
);

BOOL WINAPI QueryPerformanceCounter(
  _Out_  LARGE_INTEGER *lpPerformanceCount
);

QueryPerformanceFrequency用于获取性能计数的频率,每秒多少次,

QueryPerformanceCounter用于获取当前性能计数的值,

有了这两个API,我们就可以用来统计耗时了,思路如下:

统计耗时

那么如何得到最终的耗时呢,相信不难回答,公式如下:

秒级耗时 = (结束性能计数值 - 开始性能计数值) / 性能计数频率

微秒耗时 = (结束性能计数值 - 开始性能计数值)* 1000000 / 性能计数频率

微秒计时实现

LARGE_INTEGER freq_;
QueryPerformanceFrequency(&freq_);

LARGE_INTEGER begin_time;
LARGE_INTEGER end_time;
QueryPerformanceCounter(&begin_time);
Sleep(100);
QueryPerformanceCounter(&end_time);

double ns_time = (end_time.QuadPart - begin_time.QuadPart) * 1000000.0 / freq_.QuadPart;

封装微秒计时的实现

虽然上面已经实现了微秒精度计时,但是由于每次调用API时,都要定义变量等,使用起来肯定会有很多重复或者类似的代码,那么为了避免这种情况,对此实现进行了封装,如下:

class stop_watch
{
public:
    stop_watch()
        : elapsed_(0)
    {
        QueryPerformanceFrequency(&freq_);
    }
    ~stop_watch(){}
public:
    void start()
    {
        QueryPerformanceCounter(&begin_time_);
    }
    void stop()
    {
        LARGE_INTEGER end_time;
        QueryPerformanceCounter(&end_time);
        elapsed_ += (end_time.QuadPart - begin_time_.QuadPart) * 1000000 / freq_.QuadPart;
    }
    void restart()
    {
        elapsed_ = 0;
        start();
    }
    //微秒
    double elapsed()
    {
        return static_cast<double>(elapsed_);
    }
    //毫秒
    double elapsed_ms()
    {
        return elapsed_ / 1000.0;
    }
    //
    double elapsed_second()
    {
        return elapsed_ / 1000000.0;
    }

private:
    LARGE_INTEGER freq_;
    LARGE_INTEGER begin_time_;
    long long elapsed_;
};

那么,如何使用此封装的类呢,来看一下调用的例子:

stop_watch watch;
watch.start();
Sleep(100);
watch.stop();
cout << watch.elapsed() << " ns" << endl;

看看调用是不是更方便了呢,是不是有点似曾相识的感觉,对,没错,你猜对了。。。

参考资料

QueryPerformanceFrequency

QueryPerformanceCounter

posted on 2014-12-27 16:12  缘生梦  阅读(15225)  评论(2编辑  收藏  举报