FPS counter problem

Started by
14 comments, last by Aram 21 years, 8 months ago
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.
Advertisement
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
Could someone explain RDTSC? Never heard of this before and has been mensioned a few times...
True words are not always beautiful, beautiful words are not always truthful.
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:

      /* 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]
Hmm...Havent woked much in assembly before, just some in school for hardware programmming... but thanks anyway maybe I''ll manage to get something off it.

Thanks!
True words are not always beautiful, beautiful words are not always truthful.

This topic is closed to new replies.

Advertisement