このテストプログラムで質問してみましょう。
#include <iostream>
#include <chrono>
using std::chrono::nanoseconds;
using std::chrono::duration_cast;
int main(int argc, char* argv[])
{
std::cout << "resolution (nano) = " << (double) std::chrono::high_resolution_clock::period::num
/ std::chrono::high_resolution_clock::period::den * 1000 * 1000 * 1000 << std::endl;
auto t1 = std::chrono::high_resolution_clock::now();
std::cout << "how much nanoseconds std::cout takes?" << std::endl;
auto t2 = std::chrono::high_resolution_clock::now();
auto diff = t2-t1;
nanoseconds ns = duration_cast<nanoseconds>(diff);
std::cout << "std::cout takes " << ns.count() << " nanoseconds" << std::endl;
return 0;
}
私のマシンでの出力:
解像度(ナノ)= 100
std :: coutにかかるナノ秒数は?
std :: coutには1000200ナノ秒かかります
結果として1000200
または1000300
または1000400
または1000500
または1000600
または2000600
のいずれか(= 1または2マイクロ秒)を受け取ります。明らかにstd::chrono
の解像度はnot 100ナノ秒またはstd::cout
の時間を測定する方法が間違っています。 (なぜ1500000
?のように1〜2マイクロ秒の間に何かを受信しないのですか?)
C++で高解像度のタイマーが必要です。同じマシンでC#Stopwatch
クラスを使用してマイクロ秒の精度で物事を測定できるため、OS自体が高解像度タイマーを提供します。そのため、OSに搭載されている高解像度タイマーを正しく使用する必要があります。
予想される結果を得るためにプログラムを修正するにはどうすればよいですか?
VS2012を使用していると思います。そうでない場合は、この答えを無視してください。 VS2012 typedef
のhigh_resolution_clock
からsystem_clock
。悲しいことに、これは安っぽい精度(約1ms)を持っていることを意味します。私はVS2012で使用するためにQueryPerformanceCounter
を使用するより良い高解像度クロックを書きました...
HighResClock.h:
struct HighResClock
{
typedef long long rep;
typedef std::nano period;
typedef std::chrono::duration<rep, period> duration;
typedef std::chrono::time_point<HighResClock> time_point;
static const bool is_steady = true;
static time_point now();
};
HighResClock.cpp:
namespace
{
const long long g_Frequency = []() -> long long
{
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
return frequency.QuadPart;
}();
}
HighResClock::time_point HighResClock::now()
{
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
return time_point(duration(count.QuadPart * static_cast<rep>(period::den) / g_Frequency));
}
(アサートと#ifsを省き、上記のコードから2012年にコンパイルされているかどうかを確認します)
この時計は、どこでも標準時計と同じように使用できます。
クロックの分解能は、クロックが使用するデータ型で表すことができる最小の持続時間と必ずしも同じではありません。この場合、実装では100ナノ秒という短い期間を表すことができるデータ型を使用しますが、基になるクロックには実際にそのような解像度はありません。
Visual Studioの_high_resolution_clock
_の低解像度は、数年前から問題となっています。 MicrosoftのC++標準ライブラリメンテナー、Stephan T. Lavavej、 示されています これはQueryPerformanceCounter()
の使用によりVS2015で修正されました。
たぶん、実装は高解像度タイマーを実装していませんか?
あなたはWindowsを使用しているようです(C#に言及しています)ので、タイマーで実際にWindowsを使用している場合は、 QueryPerformanceFrequency および QueryPerformanceCounter を使用できます。