c++assemblycpuid

How to use CPUID as a serializing instruction?


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":::);

Solution

  • 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?