2016-12-27 12 views
0

私が呼ぶたび:std :: chronoは繰り返しQueryPerformanceFrequencyを呼び出しますか?

std::chrono::high_resolution_clock::now().time_since_epoch().count(); 

それのためのアセンブリ命令は、次のとおりです。

std::chrono::high_resolution_clock::now().time_since_epoch().count(); 
00007FF7D9E11840 call  qword ptr [__imp__Query_perf_frequency (07FF7D9E14090h)] 
00007FF7D9E11846 call  qword ptr [__imp__Query_perf_counter (07FF7D9E140A0h)] 

私は前に、Windows APIのクロックを使用してきましたし、私は正しい道を一度周波数を照会することだと思いました。 Microsoftのドキュメントで

それは言う:

QueryPerformanceFrequencyパフォーマンス カウンタの周波数を取得します。パフォーマンスカウンタの周波数はシステム で固定されており、すべてのプロセッサで一貫しています。したがって、周波数 はアプリケーションの初期化時に照会する必要があり、結果は にキャッシュできます。

これはループしていたので、QueryPerformanceFrequencyの呼び出しは繰り返し実行されると思います。これはリリースモードと/ O2の最適化で構築されました。私はデバッグモードでビルドする場合

また、以下の組み立てを行います

std::chrono::high_resolution_clock::now().time_since_epoch().count(); 
00007FF774FC9D19 lea   rcx,[rbp+398h] 
00007FF774FC9D20 call  std::chrono::steady_clock::now (07FF774FB1226h) 
00007FF774FC9D25 lea   rdx,[rbp+3B8h] 
00007FF774FC9D2C mov   rcx,rax 
00007FF774FC9D2F call  std::chrono::time_point<std::chrono::steady_clock,std::chrono::duration<__int64,std::ratio<1,1000000000> > >::time_since_epoch (07FF774FB143Dh) 
00007FF774FC9D34 mov   rcx,rax 
00007FF774FC9D37 call  std::chrono::duration<__int64,std::ratio<1,1000000000> >::count (07FF774FB1361h) 

私はアセンブリを理解していない、とリリースモードでのWindows APIへの呼び出しがある理由を私は知りませんデバッグモードではそれについて言及していません。また、私はVisual Studio上です。

ありがとうございました。

+0

しかし、「QueryPerformanceFrequency」は2回目です – Rakete1111

+0

これは、C++の標準的な問題ではなく、コンパイラ固有の問題をより多く見かけます。 フラグを編集し、使用するコンパイラとバージョンを指定することをお勧めします(Visual Studio IDEは異なるコンパイラを使用することがあります)。 また、私はVisual C++で提供されているC++ライブラリがMicrosoftによって作成されていると仮定しているため、QueryPerformanceFrequency()を使用するためのベストプラクティスを知っているかもしれません。 – roalz

+0

@Raketeループに入っているので、ループのたびに呼び出すことが分かります。 – Zebrafish

答えて

1

VSのオプティマイザは、QueryPerformanceFrequencyの呼び出しをループ外に置いているようではありません。最初の出力以降のすべての繰り返しで出力が常に同じであることを認識しないため、最適化できない最適化はできません。

おそらく、バグ私は(私は現時点ではVSへのアクセスを持っていないので、私はテストすることはできません)私はVSは、ループの外で、ここfooへの呼び出しを最適化することを言うと、思う:

int value = 0; 
void foo() { value = 2; } 

for (int i = 0; i < 10; ++i) { 
    foo(); 
    std::cout << i * value << '\n'; 
} 

理由なぜQueryPerformance*関数への呼び出しがないのですか?デバッグでは、オプティマイザは最適化を許可されていません。オプティマイザは、ネイティブWindows APIの呼び出しが標準ライブラリ実装の呼び出しよりも高速であることを認識し、それぞれの呼び出しを置き換えます。

関連する問題