开发者

Did I implement clock drift properly?

I couldn't find any clock drift RNG code for Windows anywhere so I attempted to implement it myself. I haven't run the numbers through ent or DIEHARD yet, and I'm just wondering if this is even remotely correct...

void QueryRDTSC(__int64* tick) {
 __asm {
  xor eax, eax
  cpuid
  rdtsc
  mov edi, dword ptr tick
  mov dword ptr [edi], eax
  mov dword ptr [edi+4], edx
 }
}

__int64 clockDriftRNG() {
 __int64 CPU_start, CPU_end, OS_start, OS_end;

 // get CPU ticks -- uses RDTSC on the Processor
 QueryRDTSC(&CPU_start);
 Sleep(1);
 QueryRDTSC(&CPU_end);


 // get OS ticks -- uses the Motherboard clock
 QueryPerformanceCounter((LARGE_INTEGER*)&OS_start);
 Sleep(1);
 QueryPerformanceCounter((LARGE_INTEGER*)&OS_end);

 // CPU clock is ~1000x faster than mobo clock    
    // return raw
 return ((CPU_end - CPU_start)/(OS_end - OS_start));

    // or
 // return a random number from 0 to 9
 // return ((CPU_end - CPU_start)/(OS_end - OS_start)%10);
}

If you're wondering why I Sleep(1), it's because if I don't, OS_end - OS_start returns 0 consistently (because of the bad timer resolution, I presume).

Basically, (CPU_end - CPU_start)/(OS_end - OS_start) always returns around 1000 with a slight variation based on the entropy of CPU load, maybe temperature, quartz crystal vibration imperfections, etc.

Anyway, the numbers have a pretty decent distribu开发者_如何学编程tion, but this could be totally wrong. I have no idea.

Edit: According to Stephen Nutt, Sleep(1) may not be doing what I'm expecting, so instead of Sleep(1), I'm trying to use:

void loop() {
 __asm {
  mov ecx, 1000
  cylcles:
  nop
  loop cylcles
 }
}


The Sleep function is limited by the resolution of the system clock, so Sleep (1) may not be doing what you want.


Consider some multiplication to increase the range. Then use the result to seed a PRNG.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜