如何以C++而不是 CPU 时间测量挂钟时间



我想在C++中测量我的算法所花费的挂钟时间。许多文章都指向此代码。

clock_t begin_time, end_time;
begin_time = clock();
Algorithm();
end_time = clock();
cout << ((double)(end_time - begin_time)/CLOCKS_PER_SEC) << endl;

但这只测量我的算法占用的 CPU 时间。其他一些文章指出了这段代码。

double getUnixTime(void)
{
    struct timespec tv;
    if(clock_gettime(CLOCK_REALTIME, &tv) != 0) return 0;
    return (tv.tv_sec + (tv.tv_nsec / 1000000000.0));
}
double begin_time, end_time;
begin_time = getUnixTime();
Algorithm();
end_time = getUnixTime();
cout << (double) (end_time - begin_time) << endl;

我以为它会打印我的算法占用的挂钟时间。但令人惊讶的是,此代码打印的时间远低于先前代码打印的 cpu 时间。所以,我很困惑。请提供打印挂钟时间的代码。

那些时间可能在噪音中下降。要获得合理的时间测量值,请尝试在循环中多次执行算法:

const int loops = 1000000;
double begin_time, end_time;
begin_time = getUnixTime();
for (int i = 0; i < loops; ++i)
    Algorithm();
end_time = getUnixTime();
cout << (double) (end_time - begin_time) / loops << endl;

我在单线程程序中得到的时间大致相同:

#include <time.h>
#include <stdio.h>
__attribute((noinline)) void nop(void){}
void loop(unsigned long Cnt) { for(unsigned long i=0; i<Cnt;i++) nop(); }
int main()
{
    clock_t t0,t1;
    struct timespec ts0,ts1;
    t0=clock();
    clock_gettime(CLOCK_REALTIME,&ts0);
    loop(1000000000);
    t1=clock();
    clock_gettime(CLOCK_REALTIME,&ts1);
    printf("clock-diff: %lun", (unsigned long)((t1 - t0)/CLOCKS_PER_SEC));
    printf("clock_gettime-diff: %lun", (unsigned long)((ts1.tv_sec - ts0.tv_sec)));
}
//prints 2 and 3 or 2 and 2 on my system

但是clock的手册页只将其描述为返回近值。没有迹象表明近似值与clock_gettime返回的结果相当。

得到截然不同的结果是我投入多个线程的地方:

#include <time.h>
#include <stdio.h>
#include <pthread.h>
__attribute((noinline)) void nop(void){}
void loop(unsigned long Cnt) {
    for(unsigned long i=0; i<Cnt;i++) nop();
}
void *busy(void *A){ (void)A; for(;;) nop(); }
int main()
{
    pthread_t ptids[4]; 
    for(size_t i=0; i<sizeof(ptids)/sizeof(ptids[0]); i++)
        pthread_create(&ptids[i], 0, busy, 0);
    clock_t t0,t1;
    struct timespec ts0,ts1;
    t0=clock();
    clock_gettime(CLOCK_REALTIME,&ts0);
    loop(1000000000);
    t1=clock();
    clock_gettime(CLOCK_REALTIME,&ts1);
    printf("clock-diff: %lun", (unsigned long)((t1 - t0)/CLOCKS_PER_SEC));
    printf("clock_gettime-diff: %lun", (unsigned long)((ts1.tv_sec - ts0.tv_sec)));
}
//prints 18 and 4 on my 4-core linux system

这是因为 Linux 上的 musl 和 glibc 都使用 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) 来实现clock(),并且CLOCK_PROCESS_CPUTIME_ID非标准时钟在clock_gettime手册页中描述为所有进程线程的返回时间。

最新更新