システムで QueryPerformanceCounter を使用することの正確な意味を調べており、アプリケーションへの影響を理解しようとしています。4 コアのシングル CPU マシンで実行すると、実行に約 230ns かかることがわかります。24 コア 4 cpu xeon で実行すると、実行に約 1.4 ミリ秒かかります。さらに興味深いことに、私のマシンで複数のスレッドで実行すると、それらは互いに影響しません。しかし、マルチ CPU マシンでは、スレッドが相互にブロックする何らかの相互作用を引き起こします。バス上に共有リソースがあり、それらすべてがクエリを実行しているのだろうか? QueryPerformanceCounter を呼び出すと正確には何が起こり、実際には何を測定するのでしょうか?
4 に答える
Windows QueryPerformanceCounter() には、プロセッサの数を決定し、必要に応じて同期ロジックを呼び出すロジックがあります。TSC レジスタを使用しようとしますが、マルチプロセッサ システムの場合、このレジスタはプロセッサ間で同期されることが保証されていません (さらに重要なことに、インテリジェントなダウンクロックとスリープ状態によって大きく異なる可能性があります)。
MSDN によると、これがどのプロセッサで呼び出されるかは問題ではないため、このような状況で余分な同期コードがオーバーヘッドを引き起こす可能性があります。また、バス転送を呼び出す可能性があるため、バスの競合による遅延が発生する可能性があることにも注意してください。
可能であれば SetThreadAffinityMask() を使用して、特定のプロセッサにバインドしてみてください。それ以外の場合は、遅延に耐える必要があるか、別のタイマーを試すことができます (たとえば、http://en.wikipedia.org/wiki/High_Precision_Event_Timerを見てください)。
このスレッドが少し古いことは承知していますが、さらに情報を追加したいと思います。まず、特定のマシンでは QueryPerformanceCounter に時間がかかる可能性があることに同意しますが、ロンの答えが常にその理由であるかどうかはわかりません。この問題について調査を行っているときに、QueryPerformanceCounter の実装方法について説明しているさまざまな Web ページを見つけました。たとえば、Precision は Windows の精度と同じではありません。より具体的には、HAL は異なるタイミング デバイスを使用して値を取得します。これは、Windows が PIT などのより遅いタイミング デバイスを使用するようになると、時間値を取得するのにより多くの時間がかかることを意味します。明らかに、PIT を使用すると PCI トランザクションが必要になる可能性があるため、それが 1 つの理由になります。
別の記事も見つけました: How It Works: Timer Outputs in SQL Server 2008 R2 - Invariant TSC で同様の説明をしています。実際、この記事では、SQLServer がトランザクションの時間を最適な方法で調整する方法について説明しています。
その後、VM を使用している顧客に対処する必要があり、VM での時間測定には他の問題があることがわかったため、VMware のサイトで詳細を見つけました。興味のある方は、VMware の論文「VMware 仮想マシンのタイムキーピング」を参照してください。この論文では、一部のバージョンの Windows が各 TSC を同期する方法についても説明しています。したがって、特定の状況では QueryPerformanceCounter() を使用するのが安全であり、どのように機能するかを試す必要があると思います: SQL Server 2008 R2 のタイマー出力では、QueryPerformanceCounter() を呼び出したときに何が起こるかを見つけることが提案されています。
x86 では QueryPerformanceCounter() が裏で rdtsc を呼び出したという印象を受けました。マルチコアマシンで速度が低下していることに驚いています(4コアCPUで気づいたことはありません)。
これだけ使ったのは久しぶりですが、いろいろなハードウェアメーカーからガッツが提供されているので、メモリさえあればこの機能の実装はひとつではありません。
これは MSDN の小さな記事です: http://msdn.microsoft.com/ja-jp/library/cc399059.aspx
また、(1 つの CPU で複数のコアを使用するのではなく) 複数の CPU でパフォーマンスをクエリする場合は、バスを介して通信する必要があり、速度が遅くなり、ブロッキングが発生する可能性があります。
しかし、前に言ったように、かなり時間がかかりました。
マイク