linux - 非推奨 - udelay usleep 違い




gettimeofday()はマイクロ秒の分解能であることが保証されていますか? (7)

gettimeofday()の実際の解決方法はハードウェアアーキテクチャによって異なります。 IntelプロセッサとSPARCマシンには、マイクロ秒を測定する高分解能タイマーがあります。 他のハードウェアアーキテクチャはシステムのタイマーにフォールバックします。これは通常100 Hzに設定されています。 そのような場合、時間分解能はそれほど正確ではなくなります。

私は 高解像度の時間測定とタイマー、パートI からこの答えを得ました

私はもともとWin32 API用に書かれたゲームをLinuxに移植しています(よく、Win32へのOS X移植をLinuxへ移植する)。

プロセスが起動してから、uSecondsを指定して QueryPerformanceCounter を実装しました。

BOOL QueryPerformanceCounter(LARGE_INTEGER* performanceCount)
{
    gettimeofday(&currentTimeVal, NULL);
    performanceCount->QuadPart = (currentTimeVal.tv_sec - startTimeVal.tv_sec);
    performanceCount->QuadPart *= (1000 * 1000);
    performanceCount->QuadPart += (currentTimeVal.tv_usec - startTimeVal.tv_usec);

    return true;
}

これは、 QueryPerformanceFrequency() と組み合わされて、周波数として1000000という定数が与えられ、 私のマシン では uSeconds し、プログラムが起動されてからの uSeconds を含む64ビット変数を与えてくれます。

それでこれ は携帯用ですか? カーネルが特定の方法でコンパイルされていても、そのように動作していても、動作が異なることを知りたくありません。 私はそれがLinux以外のものに移植不可能であることは問題ない。


だからそれはマイクロ秒を明示的に言うが、システムクロックの分解能は指定されていないと言う。 私はこの文脈での決議はそれが今までにどれだけ最小量がそれまで増分されるであろうかを意味すると思いますか?

データ構造は、測定単位としてマイクロ秒を持つものとして定義されていますが、それはクロックやオペレーティングシステムが実際にそれを細かく測定できるという意味ではありません。

他の人が示唆しているように、 gettimeofday() は時間を設定するとクロックスキューが発生し、計算が中断される可能性があるので gettimeofday() です。 clock_gettime(CLOCK_MONOTONIC) はあなたが望むもので、 clock_getres() はあなたの時計の精度を教えてくれます。



各CPUがそれら自身のカウンタを維持し、各カウンタが他のCPUに関して同期化されることによって保証されないので、RDTSCを読むことはSMPシステムにおいて信頼できない。

clock_gettime(CLOCK_REALTIME) 試すことをお勧めします。 posixマニュアルは、これがすべての準拠システムに実装されるべきであることを示しています。 それはナノ秒のカウントを提供することができます、しかし実際の解像度が何であるかを見るためにあなたのシステムの clock_getres(CLOCK_REALTIME) をチェックすることをおそらく望むでしょう。


私の経験から、そして私がインターネットを介して読んだものから、答えは「いいえ」です、それは保証されません。 CPU速度、オペレーティングシステム、Linuxの種類などによって異なります。


この回答で は、時計の調整に関する問題について言及しています。 目盛り単位を保証する問題と調整される時間の問題の両方は、 <chrono> ライブラリを使用してC ++ 11で解決されています。

クロック std::chrono::steady_clock は調整されないことが保証されており、さらにリアルタイムに対して一定の速度で進むので、SpeedStepのような技術はそれに影響を与えてはいけません。

型安全な単位は、 std::chrono::duration などの std::chrono::duration 特殊化に変換することで取得できます。 このタイプでは、目盛り値で使用される単位についてあいまいさはありません。 ただし、時計が必ずしもこの解像度を持っているとは限らないことに注意してください。 実際には正確な時計がなくても、継続時間をアト秒に変換できます。


Intelプロセッサ向けの高解像度、低オーバーヘッドタイミング

Intelハードウェアを使用している場合は、CPUリアルタイム命令カウンタを読み取る方法は次のとおりです。 プロセッサが起動してから実行されたCPUサイクル数がわかります。 これはおそらくパフォーマンス測定のために得ることができる最もきめ細かいカウンターです。

これはCPUサイクル数です。 Linuxでは、/ proc / cpuinfoからCPU速度を取得して、秒数を取得するために除算することができます。 これをdoubleに変換するのはとても便利です。

これを私の箱の上で走らせると、

11867927879484732
11867927879692217
it took this long to call printf: 207485

これが、 インテルの開発者向けガイド で、詳細な説明がたくさんあります。

#include <stdio.h>
#include <stdint.h>

inline uint64_t rdtsc() {
    uint32_t lo, hi;
    __asm__ __volatile__ (
      "xorl %%eax, %%eax\n"
      "cpuid\n"
      "rdtsc\n"
      : "=a" (lo), "=d" (hi)
      :
      : "%ebx", "%ecx");
    return (uint64_t)hi << 32 | lo;
}

main()
{
    unsigned long long x;
    unsigned long long y;
    x = rdtsc();
    printf("%lld\n",x);
    y = rdtsc();
    printf("%lld\n",y);
    printf("it took this long to call printf: %lld\n",y-x);
}






timer