The Intel manuals for the RDTSC instruction warn that out of order execution can change when RDTSC is actually executed, so they recommend inserting a CPUID instruction in front of it because CPUID will serialize the instruction stream (CPUID is never executed out of order). My question is simple: if they had the ability to make instructions serializing, why didn't they make RDTSC serializing? The entire point of it appears to be to get cycle accurate timings. Is there a situation under which you would not want to precede it with a serializing instruction?
Newer Intel CPUs have a separate RDTSCP instruction that is serializing. Intel opted to introduce a separate instruction rather than change the behavior of RDTSC, which suggests to me that there has to be some situation where a potentially out of order timing is what you want. What is it?
Because the time stamp counter was, from memory, introduced on the Pentium.
Out-of-order execution didn't show up until the Pentium Pro, at which point it was too late to change what the instruction did.
That's actually confirmed (obtusely) in the document you provide, with the following comment about Pentium and Pentium/MMX (in 4.2, slightly paraphrased):
And, from Wikipedia:
And, from what I understand, the primary use of RDTSCP (from the i7 onwards) is to give you the processor ID as well, since each processor maintains an independent TSC. It may well be serialising but I see that more of a simple "bug fix" over the older instruction.
Well, most of the time it's to get high-resolution timestamps. At least some of the time, these timestamps are used for performance metrics. Making the intruction serializing would likely require a pipeline flush, which can be very expensive for CPU-bound applications.
Changing the behavior is almost always undesirable. Intel's customers would be disappointed to find out that
RDTSC
does something different on newer parts.If you are trying to use rdtsc to see if a branch mispredicts, the non-serializing version is what you want.
If the branch is predicted correctly, the delta will be small (maybe even negative?). If the branch is mispredicted, the delta will be large.
With the serializing version, the branch condition will be resolved because the first rdtsc waits for the math to finish.
As paxdiably explains,
RDTSC
predates the concept of "serializing" instructions because it was implemented on an in-order CPU. Adding that behavior later would change the memory access behavior of code using it, and thus be incompatible for some purposes.Instead, more recent CPUs have a related
RDTSCP
instruction that is defined as serializing (actually stronger: it promises to wait until all instructions issued before it have completed, not just that memory accesses have been done), for exactly this reason. Use that if you are running on modern CPUs.