#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "advapi32.lib")
static DWORD CPUFrequency(void)
{
DWORD freq;
HKEY hKey;
const char *key = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
DWORD buflen = 4;
RegOpenKeyExA(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey);
RegQueryValueExA(hKey, "~Mhz", NULL, NULL, (LPBYTE)&freq, &buflen);
RegCloseKey(hKey);
return freq;
}
static __declspec(naked) unsigned __int64 ReadTSC(void)
{
__asm {
rdtsc
ret
}
}
const int inner = 65536;
const int outer = 10000;
static __declspec(naked) void calibrate(void)
{
__asm {
push ebx
push esi
push edi
mov eax, dword ptr [inner]
align 16
loop_01:
sub eax, 1
jnz loop_01
pop edi
pop esi
pop ebx
ret
}
}
static __declspec(naked) void test(void)
{
__asm {
push ebx
push esi
push edi
mov eax, dword ptr [inner]
align 16
loop_01:
xor edx, ebx
xor ecx, ebx
xor esi, ebx
xor edx, ebx
xor ecx, ebx
sub eax, 1
jnz loop_01
pop edi
pop esi
pop ebx
ret
}
}
int main(int argc, char *argv[])
{
unsigned __int64 t0, t1;
double tc, tt, freq = CPUFrequency();
t0 = ReadTSC();
for (int i = 0; i < outer; i++) {
calibrate();
}
t1 = ReadTSC();
tc = (double)(t1 - t0);
t0 = ReadTSC();
for (int i = 0; i < outer; i++) {
test();
}
t1 = ReadTSC();
tt = (double)(t1 - t0);
tt -= tc;
printf("%.3f ms, %5.2f clocks per iteration, %5.2f clocks per XOR\n", tt / freq / 1000.0, tt / outer / inner, tt / outer / inner / 5);
return 0;
}