在Linux上测量增量时间时结果奇怪 [英] Strange results while measuring delta time on Linux

查看:103
本文介绍了在Linux上测量增量时间时结果奇怪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:修复了代码中的增量计算,问题仍然存在

Update: fixed delta calculations in code, still the issue remains

伙计,请您使用以下代码解释为什么我有时会得到非常奇怪的结果:

Folks, could you please explain why I'm getting very strange results from time to time using the the following code:

#include <unistd.h>
#include <sys/time.h>
#include <stdio.h>

int main()
{
  struct timeval start, end;
  long mtime1, mtime2, diff;

  while(1)
  {
    gettimeofday(&start, NULL);

    usleep(2000);

    gettimeofday(&end, NULL);

    mtime1 = (start.tv_sec * 1000 + start.tv_usec/1000.0);
    mtime2 = (end.tv_sec * 1000 + end.tv_usec/1000.0);

    diff = mtime2 - mtime1;
    if(diff > 10) 
        printf("WTF: %ld\n", diff);
  }

  return 0;
}

(您可以使用以下代码进行编译和运行: gcc test.c -o out -lrt& ./out )

(You can compile and run it with: gcc test.c -o out -lrt && ./out)

我遇到的是几乎每秒钟或更频繁地偶发的 diff 变量大值,例如:

What I'm experiencing is sporadic big values of diff variable almost every second or even more often, e.g:

$ gcc test.c -o out -lrt && ./out 
WTF: 14
WTF: 11
WTF: 11
WTF: 11
WTF: 14
WTF: 13
WTF: 13
WTF: 11
WTF: 16

这怎么可能?难怪是操作系统吗?它会进行过多的上下文切换吗?但是我的盒子闲着( 平均负载:0.02、0.02、0.3).

How can this be possible? Is it OS to blame? Does it do too much context switching? But my box is idle( load average: 0.02, 0.02, 0.3).

这是我的Linux内核版本:

Here is my Linux kernel version:

$ uname -a
Linux kurluka 2.6.31-21-generic #59-Ubuntu SMP Wed Mar 24 07:28:56 UTC 2010 i686 GNU/Linux

推荐答案

sleep函数仅确保您至少睡眠一定时间.由于Linux不是实时操作系统,因此您无法确定它只会休眠所需的时间.这是一个问题,因为您不能依靠该值.正如您所指出的,睡眠时间确实很大.

The sleep functions only make sure that you sleep AT LEAST a certain amount of time. As Linux is not a real time OS, you CAN NOT be sure that it will sleep ONLY the amount of time you want. It is a problem as you CAN NOT count on that value. As you have pointed out, it happens that the sleep time is really BIG.

Linux调度程序不能保证这一点.有了实时操作系统,您就可以做到这一点.

The Linux scheduler can not guarantee that. With a real time OS you can get that.

您的公式在某种程度上是错误的,但是我认为这不可能是您拥有如此长睡眠时间的原因.我使用此代码段检查了两个公式,结果相同:

Your formula is wrong in a way, but I think that can not be the reason why you have such big sleep time. I check the two formulae with this snippet, and I have the same result :

#include <unistd.h>
#include <sys/time.h>
#include <time.h>
#include <stdio.h>

int main()
{
  struct timeval start, end;
  long mtime, mtime2, start_time, end_time, seconds, useconds;

  while(1)
  {
    gettimeofday(&start, NULL);

    usleep(2000);

    gettimeofday(&end, NULL);

    seconds  = end.tv_sec  - start.tv_sec;
    useconds = end.tv_usec - start.tv_usec;

    mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;

    start_time = ((start.tv_sec) * 1000 + start.tv_usec/1000.0) + 0.5;
    end_time = ((end.tv_sec) * 1000 + end.tv_usec/1000.0) + 0.5;

    mtime2 = end_time - start_time;

    if(mtime > 10 || mtime2 > 10)
    {
      printf("WTF: %ld\n", mtime);
      printf("WTF2: %ld\n", mtime2);
    }
  }

  return 0;
}

结果:

$ gcc test.c -o out -lrt && ./out
WTF: 11
WTF2: 12
WTF: 21
WTF2: 21

我认为这是错误的,因为秒部分是周期性的,并且可能导致较大的负差.但是,使用带符号的长整数不会导致那么长的时间...

I thought it wrong as the useconds part is cyclic and could lead to a big negative difference. But it will not lead to such big time as you use signed long integers ...

my2cents

编辑:来自man nanosleep:

Edit : from man nanosleep :

当前的执行 nanosleep()基于正常 内核计时器机制,该机制具有 分辨率为1/HZ s(请参见time(7)). 因此,nanosleep()总是暂停 至少在指定的时间内, 但是最多可能需要10毫秒的时间 直到指定为止 再次变得可运行.对于相同的 原因,在以下情况下返回的值 * rem中的传递信号通常是 四舍五入到下一个更大的倍数 1/HZ秒.

The current implementation of nanosleep() is based on the normal kernel timer mechanism, which has a resolution of 1/HZ s (see time(7)). Therefore, nanosleep() pauses always for at least the specified time, however it can take up to 10 ms longer than specified until the process becomes runnable again. For the same reason, the value returned in case of a delivered signal in *rem is usually rounded to the next larger multiple of 1/HZ s.

这篇关于在Linux上测量增量时间时结果奇怪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆