0

I don't know what exactly does this code:

int rdtsc(){
    __asm__ __volatile__("rdtsc");

Please, someone can explain me? why "rdtsc"?

Peter Cordes
  • 286,368
  • 41
  • 520
  • 731
user17629
  • 129
  • 2
  • 5
  • Why downvoted? A similar https://stackoverflow.com/questions/56940066/rdtsc-a-a0-d-d0-what-does-this-do is upvoted. – TT_ Aug 27 '19 at 19:59

2 Answers2

9

Actually, that's not very good code at all.

RDTSC is the x86 instruction "ReaD TimeStamp Counter" - it reads a 64-bit counter that counts up at every clock cycle of your processor.

But since it's a 64-bit number, it's stored in EAX (low part) and EDX (high part), and if this code is ever used in a case where it is inlined, the compiler doesn't know that EDX is being clobbered. Or that the inline assembly sets EAX before falling off the end of a non-void function.

The compiler doesn't "understand" the assembler code, it's a black box which you must describe with input/output operands so it knows there's an output in EDX:EAX. (Or an output in EAX with EDX being clobbered). I would do this:

uint64_t rdtsc()
{
   uint32_t hi, lo;
   __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
   return ( (uint64_t)lo)|( ((uint64_t)hi)<<32 );
}

thus giving a time-count that doesn't wrap around every second or two on a modern machine, and which tells the compiler which registers your asm statement modifies.

Or use the __rdtsc() intrinsic to get the compiler to emit the rdtsc instruction itself, and know where the outputs are. See Get CPU cycle count?.

Peter Cordes
  • 286,368
  • 41
  • 520
  • 731
Mats Petersson
  • 123,518
  • 13
  • 127
  • 216
  • Comment from another user: you're missing a parenthesis in the last code block – Artjom B. Jun 15 '15 at 17:34
  • why does "=a", and "=d" work in assembly? how does it know to refer to eax/edx? – galois Oct 21 '16 at 16:56
  • The first colon in an `asm` statement describes the "output parameters", the register naming is described in the x86 part of the gcc inline assembler syntax. You can use google to search for that syntax - there are several different pages describing gcc x86 syntax. – Mats Petersson Oct 22 '16 at 06:53
  • No need for C-style casts here. Plain `uint64_t(hi) << 32 | lo` does it nicely. – Maxim Egorushkin Feb 22 '17 at 12:21
5

The often-cited inline assembly for rdtsc produces supeflous code with gcc-7 and earlier versions.

A more efficient solution is to use __builtin_ia32_rdtsc built-in function:

uint64_t tsc = __builtin_ia32_rdtsc();
Maxim Egorushkin
  • 125,859
  • 15
  • 164
  • 254