【问题标题】:Getting the System tick count with basic C++?使用基本 C++ 获取系统滴答计数?
【发布时间】:2011-02-13 21:13:40
【问题描述】:

我本质上想重构 getTickCount() windows 函数,这样我就可以在基本的 C++ 中使用它,而无需任何非标准库甚至 STL。 (因此它符合 Android NDK 提供的库)

我看过

时钟()

当地时间

时间

但我仍然不确定是否可以使用时间库复制 getTickCount 窗口函数。

谁能指出我正确的方向如何做到这一点,或者即使它可能?

我想做的事情的概述:

我希望能够计算应用程序“执行”某个功能的时间。

例如,我希望能够计算应用程序尝试向服务器注册的时间

我正在尝试将它从 windows 移植到基于 linux 的 Android 上运行,这里是 windows 代码:


int TimeoutTimer::GetSpentTime() const
{
if (m_On)
{
    if (m_Freq>1)
    {
        unsigned int now;
        QueryPerformanceCounter((int*)&now);
        return (int)((1000*(now-m_Start))/m_Freq);
    }
    else
    {
        return (GetTickCount()-(int)m_Start);
    }
}
return -1;
}

【问题讨论】:

  • 你想达到什么目的?可能有办法做到这一点。也许退后一步,解释一下一般问题。
  • 好主意,我希望能够计算出应用程序“执行”某个功能的时间。因此,例如,我希望能够计算应用程序尝试向服务器注册的时间
  • 在这种情况下,查找/创建一个可以计算经过时间的对象可能非常简单。您是在寻找线程/预定时间,还是整体时钟/挂钟时间?
  • 我是从 Windows 移植它,它使用系统的经过时间,所以我不确定一个简单地检查开始和结束时间的对象是否足够。我已经在我的问题中发布了 windows 平台代码,这可能会更好地解释它

标签: c++ time android-ndk porting


【解决方案1】:

这是不可能的。 C++ 标准以及标准库对处理器或“滴答”一无所知。这可能会或可能不会在 C++0x 中通过线程支持而改变,但至少目前是不可能的。

【讨论】:

    【解决方案2】:

    您可以访问 Android 上的 vblank 中断函数(或 hblank)吗?如果是这样,为计时器增加一个全局的、可变的 var。

    【讨论】:

      【解决方案3】:

      这取决于平台,因此您只需编写一个包装器并实现每个平台的具体细节。

      【讨论】:

      • 在 Android 上只提供了非常基本的 C 库,您在此处看到的 c 库 - cplusplus.com/reference/clibrary ,它没有额外的平台特定附加功能
      • C 库确实有 time.h 不是可用的吗?它可能不会为您提供很好的时间分辨率,但应该足以满足您的需求。使用 clock() 和 CLOCKS_PER_SEC 来获取经过的时间。
      • @daramarak clock() 返回进程时间,而不是系统时间。
      【解决方案4】:

      clock() 的工作方式与 Windows 的 GetTickCount() 非常相似。单位可能不同。 GetTickCount() 返回毫秒。 clock() 每秒返回 CLOCKS_PER_SEC 滴答声。两者都有一个可以翻转的最大值(对于 Windows,大约是 49.7 天)。

      GetTickCount() 在操作系统启动时从零开始。从文档中,看起来clock() 在进程执行时开始。因此,您可以使用 GetTickCount() 比较进程之间的时间,但使用 clock() 可能无法做到这一点。

      如果您想计算某件事在单个进程中发生了多长时间,并且您不担心翻转:

      const clock_t start = clock();
      // do stuff here
      clock_t now = clock();
      clock_t delta = now - start;
      double seconds_elapsed = static_cast<double>(delta) / CLOCKS_PER_SEC;
      

      澄清:clock() 是否返回经过的墙上时间或处理器时间似乎存在不确定性。我检查的前几个参考资料说的是墙上时间。例如:

      Returns the number of clock ticks elapsed since the program was launched.

      诚然,这有点含糊。 MSDN 更明确:

      The elapsed wall-clock time since the start of the process....

      用户 darron 说服我深入挖掘,因此我找到了 C 标准 (ISO/IEC 9899:TC2) 的草稿副本,上面写着:

      ...返回实现对使用的处理器时间 ...

      的最佳近似值

      我相信我曾经使用过的每个实现都会给出挂钟时间(我想这是所用处理器时间的近似值)。

      结论:如果您想计时这样的代码,以便您可以对各种优化进行基准测试,那么我的回答是合适的。如果您尝试根据实际挂钟时间实现超时,则必须检查 clock() 的本地实现或使用记录在案的其他函数来提供经过的挂钟时间。

      更新:在 C++11 中,还有标准库的一部分,它提供了各种时钟和类型来捕获时间和持续时间。虽然标准化且广泛可用,但尚不清楚 Android NDK 是否完全支持。

      【讨论】:

      • 这不是真的。 clock() 返回进程花费的时间,通常远小于系统总时间。
      • @darron:我没有说 clock() 返回系统时间。事实上,我在第二段中指出了差异。该问题要求一种方法来计算使用标准 C++ 库需要多长时间。我的回答解释了如何做到这一点。
      • 嗯,第一段和最后一段似乎忽略了第二段的存在。示例代码将为您提供进程本身的时间,而不是自“开始”以来的挂钟时间。因此,如果您有一个非常轻量级的进程运行了几天,那么它的时钟可能只有 5 秒。它根本不类似于 GetTickCount(),除了松散地计时。我知道这是一个老问题/答案,但人们仍然会找到这些东西并尝试使用提供的信息。
      • @darron:好的,我现在明白你的意思了。我使用的每个clock() 实现都返回了挂钟时间,而不是处理器时间。我已经更新了答案以反映这一点。
      • 嗯...奇怪。我使用的每个实现都是处理器时间。 (即:在运行轻量级任务几天后给出 2 分钟增量的值)我发现了一些对 VC++ 做挂钟时间的参考(正如你的 MSDN 摘录所说)。
      【解决方案5】:

      在 Android NDK 上,您可以使用 POSIX clock_gettime() 调用,它是 libc 的一部分。这个函数是各种 Android 计时器调用结束的地方。

      例如,java.lang.System.nanoTime() 是这样实现的:

      struct timespec now;
      clock_gettime(CLOCK_MONOTONIC, &now);
      return (u8)now.tv_sec*1000000000LL + now.tv_nsec;
      

      此示例使用单调时钟,这是您在计算持续时间时需要的。与挂钟不同(可通过 gettimeofday() 获得),当网络提供商更改设备的时钟时,它不会向前或向后跳跃。

      clock_gettime() 的 Linux 手册页描述了其他可用的时钟,例如每个线程经过的 CPU 时间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-18
        • 1970-01-01
        • 2021-12-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多