3

I am trying to convert someone else's project from 32bit to 64bit. Everything seems to be OK except one function, which uses assembly expressions which are not supported in Visual Studio when building x64:

// Returns the Read Time Stamp Counter of the CPU
// The instruction returns in registers EDX:EAX the count of ticks from processor reset.
// Added in Pentium. Opcode: 0F 31.
int64_t CDiffieHellman::GetRTSC( void )
{
    int tmp1 = 0;
    int tmp2 = 0;

#if defined(WIN32)
    __asm
    {
        RDTSC;          // Clock cycles since CPU started
        mov tmp1, eax;
        mov tmp2, edx;
    }
#else
    asm( "RDTSC;\n\t"
        "movl %%eax, %0;\n\t"
        "movl %%edx, %1;" 
        :"=r"(tmp1),"=r"(tmp2)
        :
        :
        );
#endif

    return ((int64_t)tmp1 * (int64_t)tmp2);
}

Most funny thing about this is, that this is being used for generating random numbers. Neither asm block compiles under x64, so playing with ifdef doesn't help. I just need to find C/C++ replacement to avoid rewriting whole program.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778

1 Answers1

7

For the Windows branch,

#include <intrin.h>

and call the __rdtsc() intrinsic function.

Documentation on MSDN

For the Linux branch, the intrinsic is available under the same name, but you need a different header file:

#include <x86intrin.h>
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • But there's that thing... The original code somehow uses 2 integers and then multiplies them. I'm not exactly sure what's the result of that operation - and how to do it with that single timestamp. So far I'll just return the timestamp as-is. – Tomáš Zato Sep 21 '15 at 07:07
  • @TomášZato: As you can read in the comment (which is correct), the upper 32 bits of the result end up in `EDX` and the lower 32 bits in `EAX`. So `__rdtsc()` intrinsic will give you the real timestamp, i.e. `(EDX << 32ULL) | EAX`. To reproduce the original formula you would use `uint64_t tsc = __rdtsc(); return (tsc >> 32) * (tsc & 0xFFFFFFFF);`, but this is less random than the original and not uniform, so... I think it's better to not do the multiplication. – Ben Voigt Sep 21 '15 at 14:58