C或C ++中的亚毫秒精度时序

时间:2010-05-25 13:10:03

标签: c++ c time

在C或C ++中获得亚毫秒精度计时数据有哪些技术/方法,它们提供的精度和准确度如何?我正在寻找不需要额外硬件的方法。该应用程序涉及等待大约50微秒+/- 1微秒,而一些外部硬件收集数据。

编辑:操作系统是Wndows,可能是VS2010。如果我可以在Linux上获得硬件的驱动程序和SDK,我可以使用最新的GCC去那里。

9 个答案:

答案 0 :(得分:14)

在处理现成的操作系统时,准确的计时是一项非常困难且涉及的任务。如果您真的需要保证时间,唯一真正的选择是完整的实时操作系统。但是,如果“几乎总是”足够好,可以使用一些技巧,这些技巧可以在商品Windows和Windows下提供良好的准确性。 Linux的

  1. 使用Sheilded CPU基本上,这意味着关闭所选CPU的IRQ亲和力&为计算机上的所有其他进程设置处理器关联掩码,以忽略您的目标CPU。在您的应用程序上,将CPU关联性设置为仅在屏蔽的CPU上运行。实际上,这应该可以防止操作系统暂停您的应用程序,因为它始终是该CPU唯一可运行的进程。
  2. 绝不允许让您的流程自愿控制操作系统(对于非实时操作系统而言,这本质上是不确定的)。没有内存分配,没有套接字,没有互斥,nada。使用RDTSC在while循环中旋转,等待目标时间到达。它将消耗100%的CPU,但这是最准确的方法。
  3. 如果数字2有点过于苛刻,您可以“瞌睡”,然后将CPU刻录到目标时间。在这里,您可以利用操作系统以设定的时间间隔调度CPU的事实。通常每秒100次或每秒1000次,具体取决于您的操作系统和配置(在Windows上,您可以使用多媒体API将默认调度周期更改为100 / s至1000 / s)。这可能有点难以正确,但基本上您需要确定OS调度周期何时发生并计算目标唤醒时间之前的那个。在这个持续时间内休眠然后,在醒来时,旋转RDTSC(如果你在一个CPU上......如果没有,则使用QueryPerformanceCounter或Linux等效物)直到你的目标时间到来。有时,操作系统调度会让你错过,但一般来说,这种机制非常有效。
  4. 这似乎是一个简单的问题,但是当你的时间限制越来越严格时,获得“好”的时间会越来越困难。祝你好运!

答案 1 :(得分:5)

硬件(因此分辨率)因机器而异。在Windows上,特别是(我不确定其他平台),您可以使用QueryPerformanceCounterQueryPerformanceFrequency,但请注意,您应该从同一个线程调用这两个并且没有关于解决方案的严格保证(允许QueryPerformanceFrequency返回0表示没有高分辨率计时器可用。但是,在大多数现代桌面上,应该有一个精确到微秒。

答案 2 :(得分:2)

boost :: datetime具有微秒精度时钟,但其精度取决于平台。

文档说明:

ptime microsec_clock :: local_time() “使用亚秒级分辨率时钟获取当地时间。在Unix系统上,这是使用GetTimeOfDay实现的。在大多数Win32平台上,它是使用ftime实现的.Win32系统通常无法通过此API实现微秒级分辨率。如果更高的分辨率对您的应用程序测试您的平台以查看已达到的分辨率。“

http://www.boost.org/doc/libs/1_43_0/doc/html/date_time/posix_time.html#date_time.posix_time.ptime_class

答案 3 :(得分:1)

您可以尝试以下方法:

struct timeval t; 函数gettimeofday(& T公司,为0x0);

这为您提供以微秒为单位的当前时间戳。我不确定准确性。

答案 4 :(得分:0)

您可以尝试使用here描述的技术,但它不可移植。

答案 5 :(得分:0)

大多数现代处理器都有定时或其他仪器用途的寄存器。例如,在Pentium天以来的x86上有RDTSC指令。您可以使用编译器访问此指令。

有关详细信息,请参阅wikipedia

答案 6 :(得分:0)

sys / time.h中的timeval有一个成员'tv_usec',即微秒。

此链接和下面的代码将有助于说明:

http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/time.h.html

timeval start;
timeval finish;

long int sec_diff;
long int mic_diff;

gettimeofday(&start, 0);
cout << "whooo hooo" << endl;
gettimeofday(&finish, 0);

sec_diff = finish.tv_sec - start.tv_sec;
mic_diff = finish.tv_usec - start.tv_usec;

cout << "cout-ing 'whooo hooo' took " << sec_diff << "seconds and " << mic_diff << " micros." << endl;

gettimeofday(&start, 0);
printf("whooo hooo\n");
gettimeofday(&finish, 0);

sec_diff = finish.tv_sec - start.tv_sec;
mic_diff = finish.tv_usec - start.tv_usec;

cout << "fprint-ing 'whooo hooo' took " << sec_diff << "seconds and " << mic_diff << " micros." << endl;

答案 7 :(得分:0)

祝你好运用MS Windows做到这一点。您需要一个实时操作系统,也就是说,保证时间可重复的操作系统。 Windows可以在不合适的时刻切换到另一个线程甚至另一个进程。您也无法控制缓存未命中。

当我进行实时机器人控制时,我使用了一个名为OnTime RTOS32的非常轻量级的操作系统,它具有部分Windows API仿真层。我不知道它是否适合你正在做的事情。但是,对于Windows,您可能永远无法证明它永远不会无法及时给出响应。

答案 8 :(得分:0)

GetSystemTimeAsFileTimeQueryPerformanceCounter的组合可以生成一套可靠的代码,以便在Windows上获得微秒级解析时间服务。

请在此处查看另一个帖子中的this评论。