2011-12-20 13 views
6

私はwindowsに私のアプリケーションを移植しています。unixから壁に入っています。私のアプリケーションでは、マイクロ秒単位で時間を見つける必要があります(アプリケーション全体が高精度のアプリケーションであるため、それに大きく依存しています)。timespec相当のウィンドウ

以前はtimespec構造を使用していましたが、ウィンドウにそのようなものは含まれていません。コマンドGetTickCountは、時間がミリ秒単位で返されるため、十分ではありません。私もQueryPerformanceFrequencyを考えていた。

誰もができるだけtimespecと同じであることを知っているだろうか、将来私はナノ秒も要求するかもしれません。彼らの助け

+0

QueryPerformanceCounterに問題がありますか? – kichik

+0

@kichikデュアルコアCPUと一緒に使うと動作すると聞きました。完全に真であるかどうかわからない – Quillion

+0

新しい(vs2015、v14.0.xyzにバンドルされている)ランタイムには、timespecタイプ(実際には_timespec32、_timespec64、およびtimespecの3つの異なるタイプ)を定義するヘッダーが含まれています。残念ながら、このタイプの存在をテストするための付随するマクロ(_TIMESPEC_DEFINEDなど)はありません。 –

答えて

10

参照、例えば、How to realise long-term high-resolution timing on windows using C++?C++ Timer function to provide time in nano secondsのための誰に

感謝。

Windows XPでCygwinでいくつかのテストを行いました。私のマシンでは、gettimeofday()の粒度は約15ミリ秒(約1/64秒)です。それはかなり粗いです。 (最初のための1000000を有することができるPOSIX)

* clock_t clock(void) (divisor CLOCKS_PER_SEC) 
* clock_t times(struct tms *) (divisor sysconf(_SC_CLK_TCK)) 

どちらの約数が1000以下のとおりですので、の粒度です。

また、clock_getres(CLOCK_REALTIME、...)は15ミリ秒を返しますので、clock_gettime()は役に立ちません。 CLOCK_MONOTONICとCLOCK_PROCESS_CPUTIME_IDは機能しません。

その他の可能性のあるWindowsの可能性がありますRDTSC;ウィキペディアの記事を参照してください。 Windows XPでは利用できないHPETがあります。

Linuxではclock()が処理時間ですが、Windowsでは壁面時間です。

だから、いくつかのサンプルコード、両方の標準的なUnixのため、および( のマシン上で)約50マイクロ秒の精度を与えるWindowsで実行CYGWINコード、ため。戻り値は秒単位で、関数が最初に呼び出されてから経過した秒数を示します。 (私は後天的にこれが私が a year agoを与えた答えであることに気付いた)。 std::chrono::high_resolution_clock:Windowsの、UNIX、Linux、および漠然と近代的なものとのポータブル

#ifndef __CYGWIN32__ 
double RealElapsedTime(void) { // returns 0 seconds first time called 
    static struct timeval t0; 
    struct timeval tv; 
    gettimeofday(&tv, 0); 
    if (!t0.tv_sec) 
     t0 = tv; 
    return tv.tv_sec - t0.tv_sec + (tv.tv_usec - t0.tv_usec)/1000000.; 
} 
#else 
#include <windows.h> 
double RealElapsedTime(void) { // granularity about 50 microsecs on my machine 
    static LARGE_INTEGER freq, start; 
    LARGE_INTEGER count; 
    if (!QueryPerformanceCounter(&count)) 
     FatalError("QueryPerformanceCounter"); 
    if (!freq.QuadPart) { // one time initialization 
     if (!QueryPerformanceFrequency(&freq)) 
     FatalError("QueryPerformanceFrequency"); 
     start = count; 
    } 
    return (double)(count.QuadPart - start.QuadPart)/freq.QuadPart; 
} 
#endif 
+0

まったく問題はありませんが、なぜ二重の値が返されるのか、何が表現されるのかを理解できないようです。私はあなたが違いを見いだし、次に周波数で分けることを理解しています。ですから、二重の値が秒であると仮定すると、マイクロ秒を見つけるために、私は100万(1 000 000)を掛けなければなりません。そうですか? – Quillion

+0

戻り値は 'seconds'であり、関数が最初に呼び出されてから経過した秒数を返します。 –

+0

[GNU C Lib Manual](http://www.gnu.org/s/hello/manual/libc/Elapsed-Time.html)には、いくつかの特有のオペレーティングシステムがありますが、tv_secメンバには符号なしタイプがありますこれらのために、上記のコードは、キャストが必要です、またはクロックが決して後方に走らないという前提が必要です。 –

2

。解決方法はさまざまですが、コンパイル時にそれが何であるかを知ることができます。現代のハードウェアではナノ秒が確かに可能です。

ナノ秒の精度は実際にはサブメートルの精度を意味することに注意してください。光速でのナノ秒はわずか30センチメートルです。コンピュータをラックの最上部から最下部に移動すると、文字通り数ナノセカンド移動します。