Boost logo

Boost :

From: Matthew Hurd (matt_at_[hidden])
Date: 2003-03-24 21:08:50


Replying to myself sorry...

> Quite right. This was related to the QueryPerformanceCounter() using the
> 8254-compatible real-time clock which could take several thousand cycles.
> The HAL of Pentium's and above should use Intel's RDTSC (Read Time Stamp
> Counter) and not suffer this problem.

Apart from problems with RDTSC mentioned elsewhere (PCI problems, CPU speed
changes, problems with >2.1GHz) ... I'm not sure when RDTSC is used as there
seems to be a bit of information indicating uniprocessor HAL's using the
real-time clock instead of RDTSC, including boost

http://lists.boost.org/MailArchives/boost/msg31392.php

Couldn't find anything definitive at MS. Others might know.

The last bit of
http://msdn.microsoft.com/msdnmag/issues/0500/hood/default.aspx seemed the
most (in)definitive google turned up.

But it seems only the multiprocessor HAL (which can run on a uniprocessor
but is not the default) supports RDTSC. If this is the case then timing
granularity will vary quite a bit per platform.

Could code RDTSC directly (note quite portable C++ ;-))....

P J Naughter and J M McGuiness wrote the following code that is publicly
available but copyrighted:
http://www.thecodeproject.com/datetime/ccputicker.asp#xx1843xx

But this would need to be different for each supported compiler :-( and you
still have to calculate the processor frequency, perhaps using
QueryPerformanceCounter() on win32... :-(

#pragma optimize("",off)
void CCPUTicker::Measure()
{
        if (m_bHasRDTSC)
        {
                volatile ULARGE_INTEGER ts;

                     //on NT don't bother disabling interrupts as doing
                    //so will generate a priviledge instruction exception
                if (!m_bRunningOnNT)
                {
                        _asm
                        {
                                cli
                        }
                }

                _asm
                {
                        xor eax,eax
                      push eax
                      push ebx
                        push ecx
                        push edx
                        _emit 0x0f ; cpuid - serialise
the processor
                        _emit 0xa2
                        pop edx
                        pop ecx
                      pop ebx
                        pop eax
                        _emit 0x0f ; rdtsc
                        _emit 0x31
                        mov ts.HighPart,edx
                        mov ts.LowPart,eax
                }

                if (!m_bRunningOnNT)
                {
                        _asm
                        {
                                sti
                        }
                }

                    m_TickCount = ts.QuadPart;
        }
        else
        {
                    m_TickCount=0;
        }
}
#pragma optimize("",on)

m_TickCount is __int64

Regards,

Matt.
--wasting too much time


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk