CPUID can be used as a serializing instruction as described here and here. What is the minimal/simplest asm syntax to use it in that way in C++?
// Is that enough?
// What to do with registers and memory?
// Is volatile necessary?
asm volatile("CPUID":::);
Is there a reason you're not using the fence operations? If the goal is to serialize a section of code you can do something like
asm __volatile__ (
" mfence \n" // drain the store buffer
" lfence \n" // and wait for that instruction to retire, draining the ROB
::: "memory"); // block compile-time reordering.
Your code here
asm __volatile__ (
" mfence \n"
" lfence \n"
::: "memory" );
This is about as much serialization as you get from cpuid
in terms of memory and instruction reordering. But neither is officially a Serializing Instruction in Intel's technical terminology.
Software prefetches aren't guaranteed to be ordered wrt. fence instructions, so on paper at least, an earlier prefetcht0
could result in data arriving after the lfence
. (But a prefetcht0
after an lfence
can't execute until after the lfence
finishes, because no instructions after an lfence
get sent to execution units until all instructions earlier have retired. "completed locally" in Intel's documentation.)
lfence
blocking instruction reordering is how Intel CPUs always work, but AMD only with an MSR setting. OSes that do Spectre mitigation set that MSR: Is LFENCE serializing on AMD processors?