I shouldn''t have to tell you this, since you should already have SEARCHED FOR IT(!):
There is an article right here on gamedev on using both timeGetTime() and the performance timers, and how to nicely use both.
FPS counter problem
Nehes OpenGl Tutorial about Lines and Antialiasing features a timer routine that uses the performance counter if installed and otherwise timeGetTime.
Im Anfang war die Tat...
Faust
Im Anfang war die Tat...
Faust
Just for info, here are the performances of various timing mechanisms, profiled on a 733MHZ machine:
Timer Profile (RDTSC):
Frequency: 733373724Hz
Resolution: 1.36356e-09s
Error: 0.000227604s
Speed: 1.38006e-07s
Timer Profile (PerformanceCounter):
Frequency: 3579545Hz
Resolution: 2.79365e-07s
Error: 0.000274057s
Speed: 1.44208e-06s
Timer Profile (TimeGetTime):
Frequency: 1000Hz
Resolution: 0.001s
Error: 0.01s
Speed: 1.82705e-07s
Timer Profile (GetTickCount):
Frequency: 1000Hz
Resolution: 0.001s
Error: 0.01s
Speed: 5.39175e-08s
Timer Profile (Clock):
Frequency: 1000Hz
Resolution: 0.001s
Error: 0s
Speed: 3.71584e-06s
Frequency and resolution are pretty obvious. Error is the average error when timing for a second and will probably be a bit off (it''s difficult to calculate error when you don''t have a fully accurate timer to test against). Speed is the time taken to execute the timer mechanism.
Enigma
Timer Profile (RDTSC):
Frequency: 733373724Hz
Resolution: 1.36356e-09s
Error: 0.000227604s
Speed: 1.38006e-07s
Timer Profile (PerformanceCounter):
Frequency: 3579545Hz
Resolution: 2.79365e-07s
Error: 0.000274057s
Speed: 1.44208e-06s
Timer Profile (TimeGetTime):
Frequency: 1000Hz
Resolution: 0.001s
Error: 0.01s
Speed: 1.82705e-07s
Timer Profile (GetTickCount):
Frequency: 1000Hz
Resolution: 0.001s
Error: 0.01s
Speed: 5.39175e-08s
Timer Profile (Clock):
Frequency: 1000Hz
Resolution: 0.001s
Error: 0s
Speed: 3.71584e-06s
Frequency and resolution are pretty obvious. Error is the average error when timing for a second and will probably be a bit off (it''s difficult to calculate error when you don''t have a fully accurate timer to test against). Speed is the time taken to execute the timer mechanism.
Enigma
Could someone explain RDTSC? Never heard of this before and has been mensioned a few times...
Newer Intel and AMD processors (don't know about other makes) support an instruction to read the processor Time Stamp Counter (which updates every cycle). This gives you a very accurate and very fast timer. It also requires inline assembly to use.
The code to use it under the Borland compiler with TASM is:
And to do it under gcc:
Note - the gcc code could probably be optimised better, I haven't used gcc assembler as much.
If you want more detail, there's an article at the Intel website:
http://www.intel.com/design/Xeon/applnots/24161821.pdf
Enigma
Edit: small typo, then edit caused source boxes to merge.
[edited by - Enigma on July 31, 2002 5:16:37 AM]
The code to use it under the Borland compiler with TASM is:
/* Code to check whether RDTSC is available */DWORD timerAvailable = 0x1; _asm{ ; Get CPU ID information mov eax, 0 cpuid ; check if CPU is GenuineIntel cmp ebx, 'uneG' jne not_intel cmp edx, 'Ieni' jne not_intel cmp ecx, 'letn' jne not_intel jmp test_RDTSC not_intel: ; check is CPU is AuthenticAMD cmp ebx, 'htuA' jne not_available cmp edx, 'itne' jne not_available cmp ecx, 'DMAc' jne not_available test_RDTSC: ; get CPU supported features mov eax, 1 cpuid ; check if TSC supported bt edx, 4 jnc not_available ; TSC supported xor timerAvailable, 1h not_available: xor timerAvailable, 1h}/* Code to read Time Stamp Counter */int64 time;int64* addr = &time__emit__(0x0f);__emit__(0x31);_asm{ ; read TSC mov esi, addr mov [esi], eax mov [esi + 4], edx}
And to do it under gcc:
/* Code to check whether RDTSC is available */DWORD timerAvailable = 0x1; asm( " /* Get CPU ID information*/\n" " movl $0, %%eax\n" " cpuid\n" " /* check if CPU is GenuineIntel*/\n" " cmpl $0x756e6547, %%ebx\n" " jne not_intel\n" " cmpl $0x49656e69, %%edx\n" " jne not_intel\n" " cmpl $0x6c65746e, %%ecx\n" " jne not_intel\n" " jmp test_RDTSC\n" "not_intel:\n" " /* check is CPU is AuthenticAMD*/\n" " cmpl $0x68747541, %%ebx\n" " jne not_available\n" " cmpl $0x69746e65, %%edx\n" " jne not_available\n" " cmpl $0x444d4163, %%ecx\n" " jne not_available\n" "test_RDTSC:\n" " /* get CPU supported features*/\n" " mov $1, %%eax\n" " cpuid\n" " /* check if TSC supported*/\n" " bt $4, %%edx\n" " jnc not_available\n" " /* TSC supported*/\n" " xor $0x1, %1\n" "not_available:\n" " xor $0x1, %1\n" : "=r" (timerAvailable) : "r" (timerAvailable) : "%eax", "%ebx", "%ecx", "%edx");/* Code to read Time Stamp Counter */int64 time;DWORD tscLowDWORD;DWORD tscHighDWORD;asm( " rdtsc\n" " mov %%eax, %0\n" " mov %%edx, %1\n" : "=a" (tscLowDWORD), "=d" (tscHighDWORD));time = (((int64)tscHighDWORD) << 32) | tscLowDWORD;
Note - the gcc code could probably be optimised better, I haven't used gcc assembler as much.
If you want more detail, there's an article at the Intel website:
http://www.intel.com/design/Xeon/applnots/24161821.pdf
Enigma
Edit: small typo, then edit caused source boxes to merge.
[edited by - Enigma on July 31, 2002 5:16:37 AM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement