Calling cpuid before rdtsc to prevent out of order?

138 Views Asked by At

I am trying to call cpuid before my rdtsc function to prevent out of order. I initially used this rdtsc function to get 2 timestamps and often I get negative numbers, which is undesirable. This is the rdtsc function, how should I implement cpuid? Or is it called int the main function?

inline uint64_t rdtsc() {
    unsigned long a, d;
    asm volatile ("rdtsc":"=a" (a), "=d" (d));
    return a | ((uint16_t)d << 32);
}
1

There are 1 best solutions below

0
Eric Postpischil On

The behavior of (uint16_t) d << 32 is not defined by the C standard.

The left operand of << is (uint16_t) d. After the cast, the integer promotions are performed, so the uint16_t value is converted to an int.1 This is likely 32 bits in your C implementation. The C standard does not define the behavior of << when the shift amount equals or exceeds with left operand width.

To fix this code, use return a | (uint64_t) d << 32;.

Most compilers warn about this. Pay attention to compiler warning messages. Preferably, elevate them to errors. (With GCC or Clang, use -Werror. With MSVC, use /WX.)

Footnote

1 This assumes int is wider than 16 bits. If int is only 16 bits, (uint16_t) d << 32 is still undefined because 32 is wider than the left operand type, 16.