1

Linuxで一定の速度で落下するポイントをシミュレートしようとしています。これが機能するためには、ミリ秒の解像度までの時間を取得する必要があります。この部分は問題ありませんが、clock_gettimeに問題があります。

'tv_nsec'フィールドが約100000000にラップアラウンドすると、ゼロ近くに戻り、clock_gettimeによって取得される時間は、前の反復で取得される時間より前になります。これは、フィールドが折り返されるたびに発生するわけではありませんが、発生することに注意してください。

デバッグするために、clock_gettimeから返された値を書き込み、デルタ値を取得しました。

反復:

gettime.seconds:1362720808、gettime.us:993649771、合計:1362721801649 us
デルタ:0.014

別の反復:

gettime.seconds:1362720808、gettime.us:993667981、合計:1362721801667 us
デルタ:0.015

別の反復:

gettime.seconds:1362720808、gettime.us:993686119、合計:1362721801686 us
デルタ:0.015

問題の反復:

gettime.seconds:1362720809、gettime.us:20032630、合計:1362720829032 us
デルタ:-972.661

デルタは秒単位であることに注意してください。これは、ミリ秒を1000で除算し、過去の時間から負の値に等しい時間を減算し、それを1000で除算すると、デルタがポジティブ。

問題を再現するためのコードは次のとおりです。

#include <iostream>
#include <sys/time.h>

using namespace std

double prevMillis = 0.0;

double getMillis()
{
    timespec ts;

    clock_gettime(CLOCK_REALTIME, &ts);

    cout << "gettime.seconds: " << ts.tv_sec << " , gettime.us: " << ts.tv_nsec << ", total: " << ((ts.tv_sec * 1000) + (ts.tv_nsec / 1000)) << " ms" << endl;

    return ((ts.tv_sec * 1000) + (ts.tv_nsec / 1000)) + 0.5;
}

int main()
{
    double delta = 0.0;

    prevMillis = getMillis();

    while(delta >= 0)
    {
        delta = (getMillis() - prevMillis) / 1000;

        prevMillis = getMillis();

        cout << "Delta: " << delta << endl << endl;
    }

    return 0;
}

クロック機能には「-lrt」を使用してコンパイルする必要があることに注意してください。

これは、問題が発生するまでループします。つまり、時間のためにデルタは負になります。私のPCでは数秒しかかかりません。

冗長な質問については申し訳ありませんが、事前に助けを得ることができます:)

4

1 に答える 1

4

tv_nsecナノ秒、つまり 1 秒の 10 億分の 1 (1/1,000,000,000) です。ただし、計算はマイクロ秒であるかのように扱っています。

修正は次のとおりです。

return ((ts.tv_sec * 1000) + (ts.tv_nsec / 1000000)) + 0.5;
                                               ^^^
于 2013-03-08T06:16:30.440 に答える