在Mac OS上测量deltatime毫秒的最佳方法是什么?

时间:2012-06-01 16:31:00

标签: c++ c macos macos-carbon

我找到了一个从Mac启动以来获得毫秒的函数:

U32 Platform::getRealMilliseconds()
{
   // Duration is a S32 value.
   // if negative, it is in microseconds.
   // if positive, it is in milliseconds.
   Duration durTime = AbsoluteToDuration(UpTime());
   U32 ret;
   if( durTime < 0 )
      ret = durTime / -1000;
   else 
      ret = durTime;

   return ret;
}

问题是,在大约20天后,AbsoluteToDuration会一直返回INT_MAX,直到Mac重新启动。

我尝试使用下面的方法,但是看起来像gettimeofday需要更多时间并且减慢游戏速度:

timeval tim;
gettimeofday(&tim, NULL);
U32 ret = ((tim.tv_sec) * 1000 + tim.tv_usec/1000.0) + 0.5;

是否有更好的方法可以获得自某个时代(自应用程序启动以来)以来经过的毫秒数?

谢谢!

2 个答案:

答案 0 :(得分:4)

您真正的问题是您正在尝试将正常运行时间内的值调整为32位整数。如果你这样做,无论你如何获得价值,你的价值总会在49天或更短的时间内回到零(或饱和)。

一种可能的解决方案是使用64位整数来跟踪时间值;这样,清算的日子被推迟了几百年,所以你不必担心这个问题。这是MacOS / X的实现:

uint64_t GetTimeInMillisecondsSinceBoot()
{
   return UnsignedWideToUInt64(AbsoluteToNanoseconds(UpTime()))/1000000;
}

...或者如果您不想返回64位时间值,那么下一个最好的方法是在程序启动时记录当前的以毫秒为单位的值,然后总是减去该值从您返回的值。这样,在你自己的程序运行至少49天之前,事情不会破裂,我认为这不太适合游戏。

uint32_t GetTimeInMillisecondsSinceProgramStart()
{
   static uint64_t _firstTimeMillis = GetTimeInMillisecondsSinceBoot();
   uint64_t nowMillis = GetTimeInMillisecondsSinceBoot();
   return (uint32_t) (nowMillis-_firstTimeMillis);
}

答案 1 :(得分:4)

我首选的方法是mach_absolute_time - 请参阅this tech note - 我使用第二种方法,即mach_absolute_time获取时间戳,mach_timebase_info获取转换所需的常量时间戳与实际时间值之间的差异(纳秒分辨率)。