代码之家  ›  专栏  ›  技术社区  ›  Paweł Hajdan

什么是timeGetTime的最佳替代品,以避免迂回?

  •  5
  • Paweł Hajdan  · 技术社区  · 16 年前

    timeGetTime 似乎很适合查询系统时间。但是,它的返回值仅为32位,因此大约每49天一次。

    在调用代码中检测滚动并不太难,但是它增加了一些复杂性,而且(更糟的)需要保持一个状态。

    有替代品吗 时间 这样就不会有这种环绕问题(可能是通过返回64位值),并且具有大致相同的精度和成本?

    8 回复  |  直到 16 年前
        1
  •  2
  •   Hans Passant    16 年前

    不,跟踪翻滚需要状态。它可以很简单,只要在每个回调上增加您自己的64位计数器。

    想要将时间段跟踪到低至1毫秒的分辨率长达49天是非常不寻常的。你不得不担心,经过这么长时间后,准确度仍然存在。下一步是使用时钟GetTickCount(64),GetSystemTimeAsFileTime的分辨率为15.625毫秒,并通过时间服务器保持精确。

        2
  •  5
  •   Len Holgate    15 年前

    你可以用 GetTickCount64() 如果你在Vista或更高版本上运行,或者合成你自己的 GetTickCount64() GetTickCount()

    GetTickCount() GetTickCount64() 在我的博客上关于测试非平凡代码的不支持它的平台上: http://www.lenholgate.com/blog/2008/04/practical-testing-17---a-whole-new-approach.html

        3
  •  5
  •   Jerry Jongerius    12 年前

    除非你需要为超过49天的活动计时, 你可以放心地忽略环绕 总是 前提是您正在计时总持续时间在49天以下的事件 . 这一切都是由于无符号模化数学在计算机内部的工作方式。

    // this code ALWAYS works, even with wrap-around!
    DWORD dwStart = timeGetTime();
    // provided the event timed here has a duration of less than 49 days
    DWORD dwDuration = timeGetTime()-dwStart;
    

    提示:查看TimeBeginPeriod(1L)以提高timeGetTime()的准确性。

    __int64 timeGetTime64() {
        static __int64 time64=0;
        // warning: if multiple threads call this function, protect with a critical section!
        return (time64 += (timeGetTime()-(DWORD)time64));
        }
    

    请注意,如果此函数未至少每49天调用一次,则此函数将无法正确检测环绕。

        4
  •  1
  •   Elrohir    16 年前

    看一看 GetSystemTimeAsFileTime() . 它充满了 FILETIME 结构,该结构包含“表示自1601年1月1日(UTC)以来的100纳秒间隔数的64位值”

        5
  •  1
  •   Stephen Nutt    16 年前

    DWORD start = timeGetTime();
    DoSomthingThatTakesLessThen49Days();
    DWORD duration = timeGetTime() - start;
    

    即使 timeGetTime 打电话时翻车了 DoSomthingThatTakesLessThen49Days duration 仍然是正确的。

    DWORD start = timeGetTime();
    DoSomthingThatTakesLessThen49Days();
    if (now + 5000 < timeGetTime())
    {
    }
    

    但可以很容易地重新编写工作如下

    DWORD start = timeGetTime();
    DoSomthingThatTakesLessThen49Days();
    if (timeGetTime() - start < 5000)
    {
    }
    
        6
  •  1
  •   Jeremy Friesner    13 年前

    // Returns current time in milliseconds
    uint64_t timeGetTime64()
    {
       static uint32_t _prevVal    = 0;
       static uint64_t _wrapOffset = 0;
    
       uint32_t newVal = (uint32_t) timeGetTime();
       if (newVal < _prevVal) _wrapOffset += (((uint64_t)1)<<32);
       _prevVal = newVal;
       return _wrapOffset+newVal;
    }
    

        7
  •  1
  •   dk123    12 年前

    我不确定这是否完全符合你的需要,但是

    std::chrono::system_clock
    

    可能和你要找的一样。

    http://en.cppreference.com/w/cpp/chrono/system_clock

        8
  •  0
  •   Kirill V. Lyadvinsky    16 年前

    RDTSC

    double get_rdtsc_coeff() {
      static double coeff = 0.0;
      if ( coeff < 1.0 ) { // count it only once
        unsigned __int64 t00 = __rdtsc();
        Sleep(1000);
        unsigned __int64 t01 = __rdtsc();
        coeff = (t01-t00)/1000.0;
      }
    
      return coeff; // transformation coefficient
    }
    

    现在,您可以获得上次重置的毫秒数:

    __int64 get_ms_from_start() {
      return static_cast<__int64>(__rdtsc()/get_rdtsc_coeff());
    }
    

    如果您的系统使用SpeedStep或类似技术,您可以使用 QueryPerformanceCounter QueryPerformanceFrequency 功能。Windows保证在系统运行时频率不能改变。