【问题标题】:timespec equivalent for windowsWindows 的 timespec 等效项
【发布时间】:2011-12-20 23:27:15
【问题描述】:

我正在将我的应用程序从unix 移植到windows,但我碰壁了。在我的应用程序中,我需要以微秒为单位找到时间(整个应用程序在很大程度上依赖于它,因为它是一个高精度的应用程序)。

以前我使用timespec 结构,但windows 不包含这样的东西。命令GetTickCount 不够用,因为它以毫秒为单位返回时间。我也在想QueryPerformanceFrequency。

会有人碰巧知道与timespec 尽可能相同的东西吗?

将来我什至可能需要纳秒,这是我在 Windows 中搜索的任何内容都不支持的。

【问题讨论】:

  • QueryPerformanceCounter 出了什么问题?
  • @kichik 我听说它在与双核 cpu 一起使用时表现不佳。不知道是不是真的
  • 新的(与 vs2015、v14.0.xyz 捆绑)运行时包含一个 标头,它定义了 timespec 类型(实际上是三种不同的类型:_timespec32、_timespec64 和 timespec)。不幸的是,没有附带的宏(例如,_TIMESPEC_DEFINED)来测试这种类型的存在(啊)。

标签: c++ c windows datetime win32-process


【解决方案1】:

例如,请参阅 How to realise long-term high-resolution timing on windows using C++? 和 C++ Timer function to provide time in nano seconds。

我在 Windows XP 下使用 Cygwin 进行了一些测试:在我的机器上,gettimeofday() 的粒度约为 15 毫秒(~1/64 秒)。这是相当粗糙的。粒度也是如此:

* clock_t clock(void) (divisor CLOCKS_PER_SEC)
* clock_t times(struct tms *) (divisor sysconf(_SC_CLK_TCK))

两个除数都是 1000(POSIX 第一个可能有 1000000)。

此外,clock_getres(CLOCK_REALTIME,...) 返回 15 毫秒,因此 clock_gettime() 不太可能有帮助。并且 CLOCK_MONOTONIC 和 CLOCK_PROCESS_CPUTIME_ID 不起作用。

Windows 的其他可能性可能是RDTSC;见维基百科文章。还有HPET,它在 Windows XP 中不可用。

还要注意,在 Linux 中,clock() 是进程时间,而在 Windows 中是挂钟时间。

因此,一些示例代码,既适用于标准 Unix,也适用于在 Windows 下运行的 CYGWIN 代码,其粒度约为 50 微秒(在 my 机器上)。返回值以秒为单位,并给出自函数第一次调用以来经过的秒数。 (我很晚才意识到这是我在a year ago 给出的答案中)。

#ifndef __CYGWIN32__
double RealElapsedTime(void) { // returns 0 seconds first time called
   static struct timeval t0;
   struct timeval tv;
   gettimeofday(&tv, 0);
   if (!t0.tv_sec)
      t0 = tv;
   return tv.tv_sec - t0.tv_sec + (tv.tv_usec - t0.tv_usec) / 1000000.;
}
#else
#include <windows.h>
double RealElapsedTime(void) { // granularity about 50 microsecs on my machine
   static LARGE_INTEGER freq, start;
   LARGE_INTEGER count;
   if (!QueryPerformanceCounter(&count))
      FatalError("QueryPerformanceCounter");
   if (!freq.QuadPart) { // one time initialization
      if (!QueryPerformanceFrequency(&freq))
         FatalError("QueryPerformanceFrequency");
      start = count;
   }
   return (double)(count.QuadPart - start.QuadPart) / freq.QuadPart;
}
#endif

【讨论】:

  • 总而言之,这似乎是一个可靠的答案,但我似乎无法弄清楚为什么会返回双精度值或它将代表什么。我知道您会发现差异,然后除以频率。因此,如果我假设 double 值以秒为单位,那么为了找到微秒,我必须乘以 100 万(1 000 000)。对吗?
  • 返回值在seconds 中,给出了自函数第一次调用以来经过的秒数。
  • GNU C Lib Manual 注意到有"some peculiar operating systems where the tv_sec member has an unsigned type." 对于这些,上面的代码需要强制转换,或者假设时钟永远不会倒转。
  • 看看Micro Second resolution timestamps on windows,尤其是Andras Vass的answer。
  • 哦,这太棒了。非常感谢您的帮助!我真的很感激!
【解决方案2】:

可在 Windows、UNIX、Linux 和任何现代的东西之间移植:std::chrono::high_resolution_clock。分辨率可能会有所不同,但您可以在编译时找出它是什么。纳秒在现代硬件上当然是可能的。

请记住,纳秒精度实际上意味着亚米精度。光速下的一纳秒只有 30 厘米。将您的计算机从机架顶部移到底部实际上是移动了几纳秒。

【讨论】:

    猜你喜欢
    • 2021-08-14
    • 2010-09-11
    • 2015-06-22
    • 2011-06-29
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多