私は使用しなければならないことを知っています:rdtsc。測定された関数は決定論的ですが、結果は再現可能にはほど遠いです(実行ごとに5%の振動が発生します)。考えられる原因は次のとおりです。
- コンテキストスイッチング
- キャッシュミス
他の原因を知っていますか?それらを排除する方法は?
私は使用しなければならないことを知っています:rdtsc。測定された関数は決定論的ですが、結果は再現可能にはほど遠いです(実行ごとに5%の振動が発生します)。考えられる原因は次のとおりです。
他の原因を知っていますか?それらを排除する方法は?
TSC(rdtscが使用するもの)は、マルチプロセッサシステムで同期されないことがよくあります。プロセスを単一のCPUにバインドするために、CPUアフィニティを設定すると役立つ場合があります。
利用可能な場合は、 HPETタイマーからタイムスタンプを取得することもできますが、同じ問題が発生する可能性はありません。
再現性に関しては、これらの差異は真実です。キャッシュを無効にしたり、プロセスにリアルタイムの優先順位を付けたり、(Linuxなどの場合)固定タイマー割り込み頻度(タイムスライシングを行うもの)を低くしてカーネルを再コンパイルしたりできます。少なくとも簡単ではなく、通常のCPUとOSの組み合わせでは、差異を完全に排除することはできません。
一般に、コーディングが簡単で、信頼性と移植性の理由から、OSが提供するものを使用することをお勧めします。高精度タイマーを提供している場合は、適切なOSヘルパーを使用してください。
(暗号システムに対してタイムアタックを試みている場合に備えて、1。このランダム性と2.正当な理由でシステムを予測不可能にする一般的な防御を備えている必要があるため、関数はそうではない可能性があります時間に関して決定論的である。)
編集:OSが提供できるタイマーに関する段落を追加しました。
編集:これはLinuxを指します。プロセスを単一のCPUにバインドするために(RDTSCから正確に読み取るために)、sched_setaffinity(2)を使用できます。そして、これが私のプロジェクトの1つからのコードで、他の目的(スレッドをCPUにマッピングする)に使用しています。これはあなたの最初の試みでなければなりません。HPETに関しては、カーネルとマシンがこれらのタイマーをサポートしている限り、これらのような通常のPOSIX呼び出しを使用できます。
なぜそれらを排除するのですか?現実的なベンチマークを作成したようですね。そのコードは、実際に使用された場合にも同じ種類の変動性を持ちます。ディスクとCPUのキャッシュレイテンシを排除した可能性が高いため、おそらくさらに悪化します。Jon Skeetのアプローチを使用して、可能な限り最高の結果をもたらす条件を作成すると、気分が良くなるだけで、決して達成できない結果が得られます。
絶対数が重要な場合は、平均ではなく中央値を計算します。
質問を参照してくださいストップウォッチのベンチマークは受け入れられますか?最新のマルチコアマルチスレッドマルチプロセスマシンでのマイクロベンチマークの分散に関する談話。
質問はJavaに関するものですが、考慮事項はどの言語のベンチマークにも当てはまります。
実際、新しい Linux カーネルには新しい perf サブシステムがあります。例:
$ ./perf stat du -s /tmp 94796 /tmp 「du -s /tmp」のパフォーマンス カウンター統計: 2.546403 task-clock-msecs # 0.060 CPU 3 コンテキストスイッチ # 0.001 M/秒 0 CPU 移行 # 0.000 M/秒 166 ページ フォールト # 0.065 M/秒 2434963 サイクル # 956.236 M/秒 1798092 命令 # 0.738 IPC 302969 ブランチ # 118.979 M/秒 26197 分岐ミス # 8.647 % 23217 キャッシュ参照 # 9.118 M/秒 4621 キャッシュミス # 1.815 M/秒 0.042406580 秒の経過時間
原因のリストに追加:分岐予測/誤予測(これは、一部のチップに複雑な予測キャッシュがあるコンテキストスイッチによって影響を受ける可能性があります。また、予測はプログラムへの異なる入力によって影響を受ける可能性があるため、2つの異なるデータの時間の直接比較セットはわずかに歪む可能性があります。
一般に、これらすべてを軽減することはほぼ不可能ですが、それぞれを支援するためにできることがいくつかあります。
ただし、もちろん、このようなタイミングを実行する最善の方法は、制御できないものによって生じる変動を最小限に抑えるように、非常に大きなデータに対して何度もタイミングを実行することです。(実際に消去することはできません。)
最新のプロセッサのほとんどは、低レベルのハードウェアパフォーマンスカウンタの驚くべきセットをサポートしています。キャッシュミスやコンテキスト切り替えのオーバーヘッドの実際の測定値など、答えを本当に知りたい場合は、PAPI(パフォーマンスAPI)ツールキットを入手してから、一部の(すべてではありませんが)OSに1つのカーネルパッチをインストールし、追加の作業を行います、あなたはオフで実行しています。