使用 gettimeofday 来测量执行时间存在的问题

之前一直使用 cprof 来分析 c/c++ 程序的性能瓶颈,可惜在 2.6 内核 + 多线程的情况下, cprof 貌似不工作了。无奈之下,使用 gettimeofday 来人肉分析。为了方便,写了这样一个类

class SP_NKClock {
    struct timeval mBornTime;
    struct timeval mPrevTime;
};

SP_NKClock :: SP_NKClock()
{   
    spnk_gettimeofday ( &mBornTime, NULL );
    spnk_gettimeofday ( &mPrevTime, NULL );
} 

long SP_NKClock :: getAge()
{
    struct timeval now;
    spnk_gettimeofday ( &now, NULL );

    return (long)( ( 1000000.0 * ( now.tv_sec - mBornTime.tv_sec )
            + ( now.tv_usec - mBornTime.tv_usec ) ) / 1000.0 );
}

long SP_NKClock :: getInterval()
{
    struct timeval now;
    spnk_gettimeofday ( &now, NULL );

    long ret = long( ( 1000000.0 * ( now.tv_sec - mPrevTime.tv_sec )
            + ( now.tv_usec - mPrevTime.tv_usec ) ) / 1000.0 );

    mPrevTime = now;

    return ret;
}


getInterval 和 getAge 都返回以毫秒为单位的时间间隔。

用这个类来分析下面这一段代码

void doSth( ... )
{
    int load = 0, process = 0, save = 0, total = 0;
    SP_NKClock clock;

    load_from_file( ...... );

    load = clock.getInterval();

    logic_process( ...... );

    process = clock.getInterval();

    save_to_file( ...... );

    save = clock.getInterval();

    total = clock.getAge();

    printf( "load %d, process %d, save %d, total %d\n",
        load, process, save, total );
}


最后打印出来的结果,有点出乎意外,就是 load + process + save != total 。

仔细想了一下,发现问题就出现 getInterval 和 getAge 返回的是毫秒,而 gettimeofday 是精确到百万分之一秒的。上面的代码中,如果各个步骤的执行时间不超过 1 毫秒,那么用 getInterval 得到的就是 0 。但是 3 个步骤加起来之后,如果超过 1 毫秒的,那么 total 的值就是 1 毫秒。

你可能感兴趣的:(多线程,C++,c,工作,C#)