マルチコアプロセッサのベンチマーク方法
-
04-10-2019 - |
質問
マルチコアプロセッサでマイクロベンチマークを実行する方法を探しています。
コンテクスト:
ほぼ同時に、デスクトッププロセッサは、パフォーマンスを予測するのを難しくしたオーダーアウトオブオーダー実行を導入しました。偶然にも、非常に正確なタイミングを取得するための特別な指示も導入しました。これらの指示の例は次のとおりです rdtsc
x86および rftb
PowerPcで。これらの命令は、システムコールによって許可されるよりも正確なタイミングを与え、プログラマーがより良くまたはさらに悪いことに、彼らの心をマイクロベンチに出すことができました。
いくつかのコアを備えた、さらにモダンなプロセッサでは、その一部はある程度眠りますが、カウンターはコア間で同期されていません。私たちはそれを言われています rdtsc
ベンチマークに使用するのはもはや安全ではありませんが、代替ソリューションを説明したときに居眠りしていたに違いありません。
質問:
一部のシステムでは、パフォーマンスカウンターを保存および復元し、API呼び出しを提供して適切な合計を読み取る場合があります。オペレーティングシステムに対するこの呼び出しが何であるかを知っている場合は、回答でお知らせください。
一部のシステムでは、コアをオフにすることができる場合があり、1つの実行のみを残します。 Mac OS X Leopardが、適切な優先ペインが開発者ツールからインストールされているときに行うことを知っています。あなたはこれが作ると思いますか rdtsc
再び使用するのは安全ですか?
より多くのコンテキスト:
マイクロベンチマークをやろうとしているときに私が何をしているのか知っていると仮定してください。あなたがアプリケーション全体をタイミングすることで最適化の利益を測定できない場合、それは最適化する価値がない、私はあなたに同意しますが、私はあなたに同意します。
代替データ構造が終了するまで、アプリケーション全体を時間をかけることはできません。これには長い時間がかかります。実際、マイクロベンチマークが約束されていない場合、私は今実装をあきらめることを決めることができました。
締め切りが制御できない出版物で提供するには数字が必要です。
解決
OSX(ARM、Intel、PowerPC)で使用したい mach_absolute_time( )
:
#include <mach/mach_time.h>
#include <stdint.h>
// Utility function for getting timings in nanoseconds.
double machTimeUnitsToNanoseconds(uint64_t mtu) {
static double mtusPerNanosecond = 0.0;
if (0.0 == mtusPerNanosecond) {
mach_timebase_info_data_t info;
if (mach_timebase_info(&info)) {
// Handle an error gracefully here, whatever that means to you.
// If you do get an error, something is seriously wrong, so
// I generally just report it and exit( ).
}
mtusPerNanosecond = (double)info.numer / info.denom;
}
return mtu * mtusPerNanosecond;
}
// In your code:
uint64_t startTime = mach_absolute_time( );
// Stuff that you want to time.
uint64_t endTime = mach_absolute_time( );
double elapsedNanoseconds = machTimeUnitsToNanoseconds(endTime - startTime);
このために1つのコアに制限する必要はないことに注意してください。 OSは、舞台裏で必要な修正を処理します mach_absolute_time( )
マルチコア(およびマルチソケット)環境で意地悪な結果を与える。
他のヒント
コアは、「RTDSC」の正しい同期値を返しています。マルチソケットマシンがある場合は、プロセスを1つのソケットに固定する必要があります。これは問題ではありません。
主な問題は、スケジューラがデータを信頼できないようにしていることです。 Linux Kernel> 2.6.31のパフォーマンスAPIがいくつかありますが、私はそれを見ていません。 Windows> Vistaはここで素晴らしい仕事をしています。QuryThreadCycletimeとQueryProcessCycletimeを使用してください。
OSXについてはわかりませんが、afaik "mach_absolute_time"はスケジュールされた時間を調整しません。