1

我正在编写以下 C 代码来获取使用 getitimer 和 setitimer 执行简单操作所需的时间。

#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>

#define INTERVAL 1        /* number of milliseconds to go off */

int main() {
    double sum = 0;
    struct itimerval initial, updated;

    initial.it_value.tv_sec     = INTERVAL;
    initial.it_value.tv_usec    = 999999;
    initial.it_interval = initial.it_value;
    memcpy(&(initial.it_interval), &(initial.it_value), sizeof( initial.it_value )); 
    printf("%ld\n", initial.it_value.tv_usec);

    if (setitimer(ITIMER_VIRTUAL, &initial, NULL) == -1) {
        perror("error calling setitimer()");
        exit(1);
    }

    for (unsigned int i; i < 100; i++) 
        sum += 1./i;

    if (getitimer(ITIMER_REAL, &updated) == -1) {
        perror("error calling getitimer()");
        exit(1);
    }

    printf("Time started = %ld\n; Time ended = %ld\n: Time taken = %ld\n",
           initial.it_value.tv_usec, updated.it_value.tv_usec,
           initial.it_value.tv_usec - updated.it_value.tv_usec);
    return 0;
}

我已经编译了:

$ gcc -o timer -std=c99 -Wall -pedantic getitimer.c -lrt -03

但是,我的答案始终是 999999(我已经提高和降低了 100):

 ./timer 
999999
Time started = 999999
; Time endd = 0
: Time taken = 999999

我的错误是什么?另外,我想问一下使用这样的程序可以获得的最高精度是多少?

非常感谢!

4

3 回答 3

1

我看到的主要是除法运算使用整数除法。所以:

initial.it_value.tv_sec     = INTERVAL/1000000;

在 tv.sec 中放置 0

initial.it_value.tv_usec    = (INTERVAL/1000000) * 1000000;

在 tv_usec 中放置 0

initial.it_interval = initial.it_value;

通常,在分配多字段结构时,使用memcpy()而不是直接分配。(直接赋值适用于初始化,但不适用于赋值。)

因此,发布的代码将“间隔”设置为 0

所以当然,结果值为 0

这是 setitimer() 和 getitimer() 手册页中的关键语句

“计时器从 it_value 递减到零,生成一个信号,然后重置为 it_interval。设置为零的计时器(it_value 为零或计时器到期且 it_interval 为零)停止。”

建议:以下已编辑

initial.it_value.tv_set = INTERVAL;
initial.it_value.tv_usec = 0;

memcpy( &(initial.it_interval), &(initial.it_value), sizeof( initial.it_value ) );

...
于 2016-02-27T06:08:36.993 回答
0

setitimer并且getitimer不是用于分析的正确功能。它们与间隔计时器有关,间隔计时器是在计时器到期时生成警报(更准确的信号)的计时器。

实现您想要的主要选项是APIclockclock_gettimeAPI。

于 2016-02-27T05:53:22.230 回答
0

最新代码的主要问题是调用getitimer()引用的是与调用不同的计时器setitime()

但是,以下代码使其易于使用

#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
//#include <limits.h>
//#include <string.h>

// do not place comments on same line as #define statement
// always surround numeric values with parens to avoid 'text replacement' errors
// wrong comment:  number of milliseconds to go off

// number of seconds in interval
#define INTERVAL (1)

// number of usec in interval
#define MICRO_INTERVAL (999999)

int main() {
    //double sum = 0;
    struct itimerval initial;
    struct itimerval updated;

    initial.it_value.tv_sec     = INTERVAL;
    initial.it_value.tv_usec    = MICRO_INTERVAL;
    initial.it_interval.tv_sec  = INTERVAL;
    initial.it_interval.tv_usec = MICRO_INTERVAL;

    // remove this line: initial.it_interval = initial.it_value;
    // remove this line: memcpy(&(initial.it_interval), &(initial.it_value), sizeof( initial.it_value ));
    //printf("%ld\n", initial.it_value.tv_usec);

    printf( "Time value: %ld.%ld\n", initial.it_value.tv_sec, initial.it_value.tv_usec );
    printf( "Time interval: %ld.%ld\n", initial.it_interval.tv_sec, initial.it_interval.tv_usec );

    if (setitimer(ITIMER_VIRTUAL, &initial, &updated) == -1)
    {
        perror("error calling setitimer()");
        exit(1);
    }

    //for (unsigned int i=0; i < 10; i++)  // must initialize the 'i' variable
    //    sum += 1./i;

    // the 'which' parameter should be 'ITIMER_VIRTUAL'
    //     as that is what was started in the call to setitimer()
    //if (getitimer(ITIMER_REAL, &updated) == -1)
    //{
    //    perror("error calling getitimer()");
    //    exit(1);
    //}

    if (setitimer(ITIMER_VIRTUAL, &initial, &updated) == -1)
    {
        perror("error calling setitimer()");
        exit(1);
    }

    printf( "end interval counter: %ld.%ld\n", updated.it_interval.tv_sec, updated.it_interval.tv_usec );
    printf( "end value counter: %ld.%ld\n", updated.it_value.tv_sec, updated.it_value.tv_usec );

    //printf("Time started = %ld\n; Time ended = %ld\n: Time taken = %ld\n",
    //       initial.it_value.tv_usec, updated.it_value.tv_usec,
    //       initial.it_value.tv_usec - updated.it_value.tv_usec);
    return 0;
}

// accuracy is +/-1 microsecond, not millisecond

结果输出,即使在两次调用之间没有做任何事情setitimer()是:

Time value: 1.999999
Time interval: 1.999999
end interval counter: 1.999999
end value counter: 2.3999
于 2016-02-27T23:24:29.873 回答