3

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日後、Macが再起動されるまでAbsoluteToDurationが常にINT_MAXを返すことです。

以下の方法を使用しようとしましたが、機能しましたが、gettimeofdayの方が時間がかかり、ゲームの速度が少し遅くなるようです。

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

あるエポックから(できればアプリが起動してから)経過したミリ秒数を取得するためのより良い方法はありますか?

ありがとう!

4

2 に答える 2

4

あなたの本当の問題は、ミリ秒単位の稼働時間の値を32ビット整数に適合させようとしていることです。これを行うと、値を取得する方法に関係なく、49日以内に値が常にゼロに戻ります(または飽和します)。

考えられる解決策の1つは、代わりに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);
}
于 2012-06-01T16:51:59.047 に答える
4

私の好みの方法は、このテクニカルノートmach_absolute_timeを参照してください。2番目の方法を使用します。つまり、タイムスタンプを取得し、タイムスタンプ間の差を実際の時間値(ナノ秒の解像度)に変換するために必要な定数を取得します。mach_absolute_timemach_timebase_info

于 2012-06-01T17:06:19.973 に答える