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

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

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

在处理现成的操作系统时,准确的计时是一项极其困难且涉及的任务。 如果你真的需要保证时间,唯一真正的选择是一个完整的实时操作系统。 但是,如果“几乎总是”足够好,可以使用一些技巧,这些技巧将在商用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调度周期何时发生并计算目标唤醒时间之前的那个。 在这个持续时间内hibernate然后,在醒来时,旋转RDTSC(如果你在一个CPU上……如果没有,则使用QueryPerformanceCounter或Linux等效物)直到你的目标时间到来。 有时候,操作系统调度会让你错过,但一般来说,这种机制非常有用。

这似乎是一个简单的问题,但是当你的时序限制越来越严格时,获得“好”的时间会越来越困难。 祝好运!

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

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

您可以尝试以下方法:

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

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

您可以尝试这里描述的技术,但它不可移植。

大多数现代处理器都有定时或其他仪器用途的寄存器。 例如,自Pentium之后的x86版本就有RDTSC指令。 您可以使用编译器访问此指令。

有关详细信息,请参阅维基百科 。

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; 

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

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

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

在这里的另一个post中看到此评论。