• Advertisement

Archived

This topic is now archived and is closed to further replies.

Getting CPU speed in asm

This topic is 5002 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi I am mking a small game in asm and need to time animations properly. I want to use RDTSC but need the CPU core speed to calculate real time. Is there any way to get the cpu frequency?

Share this post


Link to post
Share on other sites
Advertisement
On a pentium 4, you can use CPUID. The maximum operating frequency is usually given in the brand string. Also you can read from the Processor Frequency Configuration MSR on Pentium 4s and Xeons. Look in the IA-32 manuals - volume 1 and 2 for CPUID, volume 3 appendix B for MSR information.

If your processor doesnt support all that then you can link with some of the CRT time functions (windows), or you can interface directly with the 8253 hardware timer (DOS).

Share this post


Link to post
Share on other sites

Have to scroll down for the ASM section.

Not sure how much this will help, but its kind of what you need. Figured it may help.


DWORD GetCpuSpeed()
{
DWORD dwStartTicks = 0;
DWORD dwEndTicks = 0;
DWORD dwTotalTicks = 0;
DWORD dwCpuSpeed = 0;

// check for high-resolution timer

LARGE_INTEGER qwFrequency = { 0 };

if( QueryPerformanceFrequency( &qwFrequency ) && qwFrequency.QuadPart > 0 )
{
LARGE_INTEGER qwStart = { 0 };
LARGE_INTEGER qwStop = { 0 };
// 1. step - get start ticks

QueryPerformanceCounter( &qwStart );

for(;;)
{
QueryPerformanceCounter( &qwStop );

if( ( qwStop.QuadPart - qwStart.QuadPart ) * 1000 / qwFrequency.QuadPart > 1 )
{
__asm
{
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
_emit 0x0f
// CPUID

_emit 0xa2
_emit 0x0f
// RDTSC

_emit 0x31
mov [dwStartTicks], eax
}

break;
}
}

qwStart.QuadPart = qwStop.QuadPart;
// 2. step - get end ticks after 1000 ms

for(;;)
{
QueryPerformanceCounter( &qwStop );

if( ( qwStop.QuadPart - qwStart.QuadPart ) / qwFrequency.QuadPart >= 1 )
{
__asm
{
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
_emit 0x0f
// CPUID

_emit 0xa2
_emit 0x0f
// RDTSC

_emit 0x31
mov [dwEndTicks], eax
}

break;
}
}
}
else
{
DWORD dwStart = 0;
DWORD dwStop = 0;
// 1. step - get start ticks

dwStart = GetTickCount();

for(;;)
{
dwStop = GetTickCount();

if( ( dwStop - dwStart ) > 1 )
// ROLLOVER PAST 1

{
__asm
{
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
_emit 0x0f
// CPUID

_emit 0xa2
_emit 0x0f
// RDTSC

_emit 0x31
mov [dwStartTicks], eax
}

break;
}
}

dwStart = dwStop;

// 2. step - get end ticks after 1000 ms

for(;;)
{
dwStop = GetTickCount();

if( ( dwStop - dwStart ) >= 1000 )
{
__asm
{
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
_emit 0x0f
// CPUID

_emit 0xa2
_emit 0x0f
// RDTSC

_emit 0x31
mov [dwEndTicks], eax
}

break;
}
}
}

// compute result

dwTotalTicks = dwEndTicks - dwStartTicks;

dwCpuSpeed = dwTotalTicks / 1000000;

// MHz

return dwCpuSpeed;
}


[edited by - Mulligan on June 9, 2004 8:41:46 PM]

[edited by - Mulligan on June 9, 2004 8:42:18 PM]

Share this post


Link to post
Share on other sites

  • Advertisement