このブログは、株式会社フィックスターズのエンジニアが、あらゆるテーマについて自由に書いているブログです。
x86マシンでは、処理時間を計測する時、rdtsc 命令を使うと便利な場合があります。
しかし、rdtsc で取得できるタイムスタンプ値は、コア毎に同期されておらず、マザーボードやBIOSによっては、大きな差が出ることがあります。
例えば、手元のマシンは、GA-X79-UP4というマザーボードなのですが、
というようなプログラムを使って、コアごとのtsc値を出力すると、
0 357279981632826
1 357285484782081
2 357285484782262
3 357285484782228
4 357285484782206
5 357285484782070
6 357285484781877
7 357285484782047
8 357285484782285
9 357285484782194
10 357285485164683
11 357285485501430
と、なって、0番のコアだけ大きく値がずれていることがわかります。
小さいプログラムを計測する場合は、それほど問題にはならないかもしれませんが、コンテキストスイッチが入るぐらい大きなプログラムで時間計測する場合、この差が問題になる場合があります。
rdtscp 命令を使うと、この問題に対していくらか対策することができます。
rdtscp 命令は、tsc と同時に、IA32_TSC_AUX MSR に書かれている値を ECX にストアします。Linuxでは、IA32_TSC_AUX MSR には
http://lxr.free-electrons.com/source/arch/x86/kernel/vsyscall_64.c#L290
node<<12 | cpu という値が書かれているようです。
これを使って、
とすることで、どのコアでtscを取得しても、大きくずれることのない値を使うことができます。
rdtscpを使用したtsc取得のサンプルを以下に置いておきます。(NUMA環境では動きません)
https://bitbucket.org/fixstars/blog/src/d6883fea41b58666cee3d72f8a9fd82a60794d68/rdtscp.c?at=master
ただし、この方法ではcalibrate時に、OSのスケジューラがうまく動かなかった場合に、適切な値が取得できません。何度も動かせる場合は正しいらしい値が取れるまで繰り返せばよいですが、常に正しい値が必要な場合はこの方法は使えません。次回は、この問題に対応するため、Linux上で、x86のCPU_CLK_UNHALTED を読む方法について紹介するかもしれません。
また、VM上の環境ではrdtscpは使えないことがあります。注意しましょう。
コンピュータビジョンセミナーvol.2 開催のお知らせ - ニュース一覧 - 株式会社フィックスターズ in Realizing Self-Driving Cars with General-Purpose Processors 日本語版
[…] バージョンアップに伴い、オンラインセミナーを開催します。 本セミナーでは、...
【Docker】NVIDIA SDK Managerでエラー無く環境構築する【Jetson】 | マサキノート in NVIDIA SDK Manager on Dockerで快適なJetsonライフ
[…] 参考:https://proc-cpuinfo.fixstars.com/2019/06/nvidia-sdk-manager-on-docker/ […]...
Windowsカーネルドライバを自作してWinDbgで解析してみる① - かえるのほんだな in Windowsデバイスドライバの基本動作を確認する (1)
[…] 参考:Windowsデバイスドライバの基本動作を確認する (1) - Fixstars Tech Blog /proc/cpuinfo ...
2021年版G検定チートシート | エビワークス in ニューラルネットの共通フォーマット対決! NNEF vs ONNX
[…] ONNX(オニキス):Open Neural Network Exchange formatフレームワーク間のモデル変換ツー...
YOSHIFUJI Naoki in CUDAデバイスメモリもスマートポインタで管理したい
ありがとうございます。別に型にこだわる必要がないので、ユニバーサル参照を受けるよ...