定时功能通话费用

时间:2015-02-11 07:22:17

标签: c linux caching timer function-call

我试图通过CLOCK_MONOTONIC使用clock_gettime查看函数调用需要多长时间。我这样做是通过从函数调用时减去计时器开销。

我认为时间应该是一致的但是当我循环时,第一次总是比其余时间大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;
}

1 个答案:

答案 0 :(得分:3)

您具有荒谬的大值的原因是无符号差异(timepassed - timeroverhead)下溢。尝试使用带符号的整数。

编辑:顺便说一下,减去计时器开销将无法正常工作。使用CLOCK_MONOTONIC的两个clock_gettime调用之间的时间表示时间差,而不管进程,而不是cpu时间。这意味着内核调度程序可以在您的&#34;计时器开销和#34;之间停止您的进程。测量,导致比处理中时间更大的开销。

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

Edit2:你一定要坚持使用CLOCK_MONOTONIC。问题不在这里。

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

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