【问题标题】:timing function call cost计时函数调用成本
【发布时间】:2015-02-11 07:22:17
【问题描述】:

我试图查看使用clock_gettime 和CLOCK_MONOTONIC 的函数调用需要多少时间。我通过从函数调用的时间中减去计时器开销来做到这一点。

我认为时间应该是一致的,但是当我循环它时,第一次总是比其他时间大 3 倍。此外,我离开循环的时间也不同。有谁知道怎么回事?

(在 ubuntu 14.04.1 上运行 C)


编辑

我很困惑为什么循环中的第一次比其他的大得多。我现在意识到这可能与缓存有关。

我认为第一个循环缓存了计时器和函数? 但是当循环结束时,它们是否未缓存? (循环之后,函数调用时间变大了)

输出:

Within loop:
timer   w.func  difference
198     128     18446744073709551546
85      78      18446744073709551609
68      80      12
64      70      6
70      68      18446744073709551614
Outside loop:
101     115     14

我的代码:

#include <stdio.h>
#include <stdint.h>
#include <time.h>

#define NANO 1E9
#define CLOCK CLOCK_MONOTONIC
signed long long timediff(struct timespec *tstart_p, struct timespec *tstop_p)
{
    return ((tstop_p->tv_sec - tstart_p->tv_sec)*NANO + tstop_p->tv_nsec - tstart_p->tv_nsec);
}

void function()
{
}

int main()
{
struct timespec start, stop;
signed long long timepassed, timeroverhead;

printf("Within loop:\n");
printf("timer\tfunction\tdifference\n");

int i;
for (i = 0; i < 5; i++) 
{
    clock_gettime(CLOCK, &start);
    clock_gettime(CLOCK, &stop);
    timeroverhead = timediff(&start, &stop);

    clock_gettime(CLOCK, &start);
    function();
    clock_gettime(CLOCK, &stop);
    timepassed = timediff(&start, &stop);
    printf("%llu\t%llu\t%llu\n", timeroverhead, timepassed, (timepassed-timeroverhead));
}

clock_gettime(CLOCK, &start);
clock_gettime(CLOCK, &stop);
timeroverhead = timediff(&start,&stop);

clock_gettime(CLOCK, &start);
function();
clock_gettime(CLOCK, &stop);
timepassed = timediff(&start, &stop);
printf("Outside loop:\n");
printf("%llu\t%llu\t%llu\n", timeroverhead, timepassed, (timepassed - timeroverhead));


printf("\n");

return 0;
}

【问题讨论】:

标签: c linux caching timer function-call


【解决方案1】:

您的值大得离谱的原因是无符号差(timepassed - timeroverhead) 下溢。尝试使用有符号整数。

编辑:顺便说一句,减去计时器开销不会像您想象的那样起作用。使用 CLOCK_MONOTONIC 的两次clock_gettime 调用之间的时间表示与进程无关的时间差,而不是cpu 时间。这意味着您的进程可以在您的“计时器开销”测量之间被内核调度程序停止,从而导致比进程内时间更大的开销。

Tl;dr:不要尝试测量计时器开销。

Edit2:你绝对应该坚持使用 CLOCK_MONOTONIC。问题不在这里。

同样,不要尝试测量计时器开销。没有人这样做是有原因的,那是因为它在调用之间不是恒定的。 如果您不希望计时器开销很大,请调用您想要 N 次的函数,测量循环上传递的时间,然后将其除以 N。否则,您将不得不忍受计时器开销。

在没有开销的情况下获得如此高的精度的唯一方法是使用特定的 cpu 操作码,例如 rdtsc,但这当然是不可移植的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    相关资源
    最近更新 更多