質問: Intel x86/x86-64アーキテクチャで提供される`RDTSC`(Read Time Stamp Counter)命令と`RDTSCP`(Read Time-Stamp Counter and Processor ID)命令は、そのタイムスタンプカウンタ読取動作に関して何が異なるのでしょうか。 `RDTSC`では命令シリアライズが行われずOut-of-Orderプロセッサで不正確な値を読み取るが、後世代で追加された`RDTSCP`では命令シリアライズが強制されるという違いだけでしょうか? また、`RDTSCP`で同時に読み取られる`IA32_TSC_AUX` MSRの使い道も知りたいです。
回答: Intel 64 and IA-32 Architectures Software Developer’s Manualsによれば、両命令の振る舞いはそれぞれ次の通りです。 `RDTSC`命令 * `EDX:EAX`に現在のタイムスタンプカウンタ値を読みとる。 * シリアライズ命令ではないため、全ての先行命令を待機せずにカウンタ値を読み取る。同様に後続命令が読み取り操作を追い越すことも許容する。 `RDTSCP`命令 * `EDX:EAX`に現在のタイムスタンプカウンタ値を、`ECX`に`IA32_TSC_AUX` MSR(Model-Specific Register)をアトミックに読みとる。 * 全ての先行命令実行を待機してからカウンタ値を読み取る。ただし、後続命令は同読み取り操作を追い越す可能性がある。後続命令による追い越しを許容するため、`CPUID`命令のようなシリアライズ命令(serializing instructions)には区分されていない。 また`IA32_TSC_AUX`レジスタに関する下記言及がある通り、タイムスタンプカウンタ値はCPU毎に独立しているため、マルチコアプロセッサ上でどのCPU上のカウンタ値を読み取ったかの判別に用いるようです。 > > Processors based on Intel microarchitecture code name Nehalem provide an auxiliary TSC register, `IA32_TSC_AUX` that is designed to be used in conjunction with IA32_TSC. `IA32_TSC_AUX` provides a 32-bit field that is initialized by privileged software with a signature value (for example, a logical processor ID). > > > The primary usage of `IA32_TSC_AUX` in conjunction with IA32_TSC is to allow software to read the 64-bit time stamp in IA32_TSC and signature value in `IA32_TSC_AUX` with the instruction `RDTSCP` in an atomic operation. `RDTSCP` returns the 64-bit time stamp in `EDX:EAX` and the 32-bit TSC_AUX signature value in `ECX`. The atomicity of `RDTSCP` ensures that no context switch can occur between the reads of the TSC and TSC_AUX values. > > > Support for `RDTSCP` is indicated by `CPUID.80000001H:EDX[27]`. As with `RDTSC` instruction, non-ring 0 access is controlled by `CR4.TSD` (Time Stamp Disable flag). > > > User mode software can use `RDTSCP` to detect if CPU migration has occurred between successive reads of the TSC. It can also be used to adjust for per-CPU differences in TSC values in a NUMA system > > >