8

関数のパフォーマンスを測定するための良い質問を見つけました。回答では、次のようにストップウォッチを使用することをお勧めします

Stopwatch sw = new Stopwatch();
sw.Start();
//DoWork
sw.Stop();
//take sw.Elapsed

しかし、マルチ プロセッサ マシンで実行している場合、これは有効ですか? スレッドを別のプロセッサに切り替えることができますか? また、同じことが Enviroment.TickCount にもあるはずです。答えが「はい」の場合、次のようにコードを BeginThreadAffinity 内にラップする必要があります

Thread.BeginThreadAffinity();
Stopwatch sw = new Stopwatch();
sw.Start();
//DoWork
sw.Stop();
//take sw.Elapsed
Thread.EndThreadAffinity();

PS

切り替えは、プロセッサ レベルだけでなくスレッド レベルでも発生する可能性があります。たとえば、関数が別のスレッドで実行されているため、システムが別のプロセッサに切り替えることができる場合、この切り替え後にストップウォッチは有効になりますか?

私はストップウォッチをパフォーマンス測定だけに使用しているのではなく、Thread.Sleep を使用してタイマー機能をシミュレートするためにも使用しています (呼び出しの重複を防ぐため)。

4

2 に答える 2

5

関数自体がマルチスレッド化されていない場合 (たとえば、他のスレッド/プロセスを生成せず、それらが完了するのを待機しない場合)、唯一の問題はマシンにあります。

マシンが他の処理でビジー状態の場合、テストが無効になる可能性があります (CPU バウンド テストの実行中に H.264 ビデオをエンコードするなど)。同様に、メモリにバインドされているものをテストする際にすべての物理メモリを使用すると、結果が無効になる可能性があります。

したがって、一般的な原則として、このようなテストを実行するときは、マシンに最小限から通常の負荷をかける必要があります。それ以外には、マルチプロセッシングの問題はありません。はい、プログラムは実行中にコアを交換できますが、そのオーバーヘッドは測定時間のごく一部であるか、測定時間が非常に小さいため、システムの時間測定の粒度が問題になります。

于 2009-07-19T08:48:44.173 に答える
2

ストップウォッチの低レベルの実装と、実行中にプロセッサを切り替えると動作が無効になる可能性があるかどうかについて質問していると思います。実装は内部で QueryPerformanceCounter を使用します (MS BCL リファレンス ソースを参照してください。少なくとも .NET 4.0 では確認済みです)。

この API の MS ドキュメントには、次のように記載されています。

マルチプロセッサ コンピュータでは、どのプロセッサが呼び出されるかは重要ではありません。ただし、基本入出力システム (BIOS) またはハードウェア アブストラクション レイヤー (HAL) のバグにより、異なるプロセッサでは異なる結果が得られる可能性があります。

だから、あなたは正しいです。原則として問題にはなりませんが、このコメントは、実装が意図したインターフェイスと一致しない例が観察されたことを示唆しています。あなたが述べたように、測定の正確さを保証したい場合は、スレッドアフィニティを使用できます。そうは言っても、大きな違いはかなり深刻な BIOS または HAL のバグであるため、観察されたエラーは非常に小さいと推測しています。

于 2011-11-21T21:26:00.247 に答える