Clock_gettime纳秒计算

3

参考: Linux clock_gettime

我找到了一个很好的公式来获得处理时间,但是有些事情我不明白。
请看下面的结果。

前两行只是为了在各自的列中展示公式。

我只展示了快速运行的3个结果。
有趣的部分在最后一行,为什么5551 - 999896062纳秒等于18446744072709661105?
为什么18446744072709661105+1/1E9等于0.000109?

我认为有些数据转换会影响结果。

xx:      | t1.tv_sec |   | t1.tv_nsec |          | t2.tv_sec |   | t2.tv_nsec 
xx:      t2-t1(sec)      t2-t1(nsec)         (t2-t1(sec))+(t2-t1(nsec))/1E9

52291:   | 30437 |   | 999649886 |       | 30437 |   | 999759331 
52291:   0   109445          0.000109

52292:   | 30437 |   | 999772970 |       | 30437 |   | 999882416 
52292:   0   109446          0.000109

52293:   | 30437 |   | 999896062 |       | 30438 |   | 5551 
52293:   1   18446744072709661105        0.000109

源代码:

int main() {
    struct timespec t1, t2;

    int i = 0;
    while(1) {
        clock_gettime(CLOCK_MONOTONIC, &t1);
            for(int j=0;j<25000;j++) { };
        clock_gettime(CLOCK_MONOTONIC, &t2);
        printf("%d: \t | %llu | \t | %lu | \t\t | %llu | \t | %lu \n", i, (unsigned long long) t1.tv_sec, t1.tv_nsec, (unsigned long long) t2.tv_sec, t2.tv_nsec);
        printf("%d: \t %llu \t %lu \t\t %lf\n", i, (unsigned long long) t2.tv_sec - t1.tv_sec, t2.tv_nsec - t1.tv_nsec, (t2.tv_sec - t1.tv_sec)+(t2.tv_nsec - t1.tv_nsec)/1E9);
        if ((t2.tv_sec - t1.tv_sec) == 1) break;
        i++;
    }
    return 0;
}

为什么不将 clock_gettime() 的结果转换为一个以纳秒为单位的64位数字呢?这样会让生活变得容易得多。 - Maxim Egorushkin
1个回答

6

由于5551-999896062是一些负值,存储在类型为long的临时变量中,但由于%lu转换说明符,printf将其视为“unsigned long”进行解释。

请注意,struct timespec中的tv_nsec字段是long类型,而不是unsigned long类型。同样,在Linux和其他Unix系统上,time_t是有符号整数类型的typedef。因此,请在您的代码中清除所有无符号内容。

顺便说一下,减去两个timespec实例的方法是


timespec diff(timespec start, timespec end)
{
        timespec temp;
        if ((end.tv_nsec - start.tv_nsec) < 0) 
        {
                temp.tv_sec = end.tv_sec - start.tv_sec - 1;
                temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
        } 
        else 
        {
                temp.tv_sec = end.tv_sec - start.tv_sec;
                temp.tv_nsec = end.tv_nsec - start.tv_nsec;
        }
        return temp;
}

1
@resting: CLOCK_MONOTONIC 表示自某个不确定时间以来的时间(例如,在 Linux 上,零设置为系统引导时间之前的某个时间),并且是单调的,即不会改变,例如如果系统时钟被更改。CLOCK_REALTIME 表示自纪元以来的时间。 - janneb
为什么end-start会是负数? - John
@UserNotDefined:因为tv_nsec是分数纳秒吗?或者你的意思是什么? - janneb
3
tv_nsec是一个小数秒,即自tv_sec字段中的整秒以来的纳秒数。 - janneb
2
@john 因为 tv_sec 字段可能不同,所以这种情况下两个字段 (tv_nsec) 的减法结果有可能是负数。 - Feng. Ma
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接