30

このテスト プログラムで質問させてください。

#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 many nanoseconds does std::cout take?" << 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かを受け取ります(= 1 または 2 マイクロ秒)。明らかに、 の分解能が100 ナノ秒ではない、時間を測定する方法が間違っています。(たとえば、1 から 2 マイクロ秒の間で何も受信しないのはなぜですか?)10003001000400100050010006002000600std::chronostd::cout1500000

C++ で高解像度のタイマーが必要です。Stopwatch同じマシンで C# クラスを使用してマイクロ秒の精度で物事を測定できるため、OS 自体が高解像度のタイマーを提供します。だから、OS が持っている高解像度タイマーを正しく使用する必要があります。

期待どおりの結果が得られるようにプログラムを修正するにはどうすればよいですか?

4

3 に答える 3

6

クロックの分解能は、クロックが使用するデータ型で表すことができる最小期間と必ずしも同じではありません。この場合、実装では 100 ナノ秒という短い期間を表すことができるデータ型が使用されますが、基になるクロックには実際にはそのような解像度がありません。


Visual Studio の低解像度はhigh_resolution_clock、数年前から問題になっています。Microsoft の C++ 標準ライブラリ メンテナーである Stephan T. Lavavej、この問題が Visual Studio 2015 でQueryPerformanceCounter().

于 2014-12-30T19:55:03.277 に答える
1

たぶん、実装はより高い解像度のタイマーを実装していませんか?

Windowsを使用しているようです(C#について言及しています)ので、タイマーを使用していて実際にWindowsを使用している場合は、QueryPerformanceFrequencyQueryPerformanceCounterを使用できます。

于 2013-04-30T11:54:13.770 に答える