このブログは、株式会社フィックスターズのエンジニアが、あらゆるテーマについて自由に書いているブログです。
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は使えないことがあります。注意しましょう。
keisuke.kimura in Livox Mid-360をROS1/ROS2で動かしてみた
Sorry for the delay in replying. I have done SLAM (FAST_LIO) with Livox MID360, but for various reasons I have not be...
Miya in ウエハースケールエンジン向けSimulated Annealingを複数タイルによる並列化で実装しました
作成されたプロファイラがとても良さそうです :) ぜひ詳細を書いていただきたいです!...
Deivaprakash in Livox Mid-360をROS1/ROS2で動かしてみた
Hey guys myself deiva from India currently i am working in this Livox MID360 and eager to knwo whether you have done the...
岩崎システム設計 岩崎 満 in Alveo U50で10G Ethernetを試してみる
仕事の都合で、検索を行い、御社サイトにたどりつきました。 内容は大変参考になりま...
Prabuddhi Wariyapperuma in Livox Mid-360をROS1/ROS2で動かしてみた
This issue was sorted....