Skip to content

Commit f544094

Browse files
committed
Use hardware timestamps in RNG seeding
1 parent 75171f0 commit f544094

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

src/random.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <stdlib.h>
1818
#include <limits>
19+
#include <chrono>
1920

2021
#ifndef WIN32
2122
#include <sys/time.h>
@@ -43,15 +44,22 @@ static void RandFailure()
4344

4445
static inline int64_t GetPerformanceCounter()
4546
{
46-
int64_t nCounter = 0;
47-
#ifdef WIN32
48-
QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
47+
// Read the hardware time stamp counter when available.
48+
// See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
49+
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
50+
return __rdtsc();
51+
#elif !defined(_MSC_VER) && defined(__i386__)
52+
uint64_t r = 0;
53+
__asm__ volatile ("rdtsc" : "=A"(r)); // Constrain the r variable to the eax:edx pair.
54+
return r;
55+
#elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
56+
uint64_t r1 = 0, r2 = 0;
57+
__asm__ volatile ("rdtsc" : "=a"(r1), "=d"(r2)); // Constrain r1 to rax and r2 to rdx.
58+
return (r2 << 32) | r1;
4959
#else
50-
timeval t;
51-
gettimeofday(&t, NULL);
52-
nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec);
60+
// Fall back to using C++11 clock (usually microsecond or nanosecond precision)
61+
return std::chrono::high_resolution_clock::now().time_since_epoch().count();
5362
#endif
54-
return nCounter;
5563
}
5664

5765
void RandAddSeed()

0 commit comments

Comments
 (0)