[RESOLVED] CPU Clock Frequency
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9

Thread: [RESOLVED] CPU Clock Frequency

  1. #1
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,184

    [RESOLVED] CPU Clock Frequency

    Next function uses high-resolution performance counter and RDTSC (read time-stamp counter) instruction to get the CPU frequency.
    Code:
    UINT CPU::GetCPUFrequency()
    {
       LARGE_INTEGER nCntFrequency;
       if(!::QueryPerformanceFrequency(&nCntFrequency))
       {
          return 0; // high-resolution performance counter
                    // not supported
       }
       LARGE_INTEGER nCnt0, nCnt1;
       ULONG  nTs0, nTs1;
       
       HANDLE hThread  = ::GetCurrentThread();
       int nPriority   = ::GetThreadPriority(hThread);
       ::SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
       ::QueryPerformanceCounter(&nCnt1);
    
       __asm
       {
          _emit 0x0f _asm _emit 0x31 // RDTSC
          MOV nTs0, EAX
       }
       nCnt0.LowPart  = nCnt1.LowPart;		
     
       while(((ULONG)nCnt1.LowPart - (ULONG)nCnt0.LowPart) < 10000)
       {
          ::QueryPerformanceCounter(&nCnt1);
          __asm
          {
             _emit 0x0f _asm _emit 0x31 // RDTSC
             MOV nTs1, EAX
          }
       }
       ::SetThreadPriority(hThread, nPriority);
    
       ULONG nCycles = nTs1 - nTs0;
       ULONG nTicks  = (ULONG)nCnt1.LowPart - nCnt0.LowPart;
       nTicks *= 10000;
       nTicks /= (nCntFrequency.LowPart / 100);
    
       UINT nFrequency = nCycles / nTicks;
       return nFrequency; // MHz
    }
    The problem is that from some reasons the result is not exact.
    QUESTION: Does anybody know if there is another more accurate method, i.e. to read the exact frequency from somewhere?
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: http://codexpert.ro/blog/author/ovidiu-cucu/

  2. #2
    Join Date
    Dec 2002
    Location
    La Plata, Buenos Aires
    Posts
    615
    what do you mean with not exact?

  3. #3
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,184

    Re: CPU Clock Frequency

    Quote Originally Posted by indiocolifa
    what do you mean with not exact?
    Well, in my question, "not exact" it's a little bit "not corect". Sorry!

    So reformulating:
    Just... does anybody know another method(s) to get the processor frequency?
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: http://codexpert.ro/blog/author/ovidiu-cucu/

  4. #4
    Join Date
    Oct 2003
    Location
    Romania
    Posts
    127

    Re: CPU Clock Frequency

    Quote Originally Posted by ovidiucucu
    Next function uses high-resolution performance counter and RDTSC (read time-stamp counter) instruction to get the CPU frequency.
    Code:
    UINT CPU::GetCPUFrequency()
    {
       LARGE_INTEGER nCntFrequency;
       if(!::QueryPerformanceFrequency(&nCntFrequency))
       {
          return 0; // high-resolution performance counter
                    // not supported
       }
       LARGE_INTEGER nCnt0, nCnt1;
       ULONG  nTs0, nTs1;
       
       HANDLE hThread  = ::GetCurrentThread();
       int nPriority   = ::GetThreadPriority(hThread);
       ::SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
       ::QueryPerformanceCounter(&nCnt1);
    
       __asm
       {
          _emit 0x0f _asm _emit 0x31 // RDTSC
          MOV nTs0, EAX
       }
       nCnt0.LowPart  = nCnt1.LowPart;		
     
       while(((ULONG)nCnt1.LowPart - (ULONG)nCnt0.LowPart) < 10000)
       {
          ::QueryPerformanceCounter(&nCnt1);
          __asm
          {
             _emit 0x0f _asm _emit 0x31 // RDTSC
             MOV nTs1, EAX
          }
       }
       ::SetThreadPriority(hThread, nPriority);
    
       ULONG nCycles = nTs1 - nTs0;
       ULONG nTicks  = (ULONG)nCnt1.LowPart - nCnt0.LowPart;
       nTicks *= 10000;
       nTicks /= (nCntFrequency.LowPart / 100);
    
       UINT nFrequency = nCycles / nTicks;
       return nFrequency; // MHz
    }
    The problem is that from some reasons the result is not exact.
    QUESTION: Does anybody know if there is another more accurate method, i.e. to read the exact frequency from somewhere?
    I have tested your function and the result was exact as expected

  5. #5
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,184

    Re: CPU Clock Frequency

    Quote Originally Posted by marsh_pottaye
    I have tested your function and the result was exact as expected
    Well, I have already said...
    Anyhow, thanks for testing
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: http://codexpert.ro/blog/author/ovidiu-cucu/

  6. #6
    Join Date
    Oct 2004
    Posts
    1

    Re: CPU Clock Frequency

    Discussion here, on the Win32asm board: http://board.win32asmcommunity.net/v...ic.php?t=10495

    HTH

  7. #7
    Join Date
    Apr 2005
    Posts
    1

    Re: CPU Clock Frequency

    Hi,

    Here are several ideas:

    1. To correct result move RDTSC from "while" cycle like this

    while(((ULONG)nCnt1.LowPart - (ULONG)nCnt0.LowPart) < 10000)
    {
    ::QueryPerformanceCounter(&nCnt1);
    }
    __asm
    {
    _emit 0x0f _asm _emit 0x31 // RDTSC
    MOV nTs1, EAX
    }

    2. Use Sleep function when QueryPerformanceFrequency fails

    3. For Windows NT such an info can be found in HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0

  8. #8
    Join Date
    May 2005
    Posts
    1

    Re: CPU Clock Frequency

    Quote Originally Posted by neolox
    1. To correct result move RDTSC from "while" cycle like this

    while(((ULONG)nCnt1.LowPart - (ULONG)nCnt0.LowPart) < 10000)
    {
    ::QueryPerformanceCounter(&nCnt1);
    }
    __asm
    {
    _emit 0x0f _asm _emit 0x31 // RDTSC
    MOV nTs1, EAX
    }
    That's even worse. What you want is to grab the RDTSC as fast as possible so that your cycle measurement and RDTSC value is read as close as possible - that's the whole reason for making the thread a TIME_CRITICAL thread in the first place, so you're not preempted between calls. The problem with your solution is branch prediction; in all Intel chipsets you pay a high price when branch prediction fails which will cause the read of the cycles and read of the RDTSC to be even further away from one another. Remember, the point isn't to get as close to 10000 cycles as possible, it's to get enough time elapsed such that the frequency calculation actually means something.


    Quote Originally Posted by neolox
    2. Use Sleep function when QueryPerformanceFrequency fails
    All Sleep functions are based on timer interrupts; timer interrupts occur in the system excruciatingly far apart from one another, sometimes between 10 and 20 milliseconds apart. Sleep functions would do you no good to find anything out about the processor frequency.


    Quote Originally Posted by neolox
    3. For Windows NT such an info can be found in HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0
    Interesting. I didn't know about this key, too bad other OS's don't have this for each processor.

    The kicker is that there is a skew between processors in a multiprocessor system, so you still need to know which processor it is you're taking information from. One thread can be assigned to one processor, another thread using that data can be assigned to a different processor. Also, you must be careful, laptop systems and some chips with smart power management will actually slow down when they get hot or they go to sleep. When they wake back up, there's a "leap" the processor makes in the "cycles" to compensate for the time it was down. This "leap" might make you think you've got more time than there really was between two reads of the RDTSC.

    Does anyone have a better solution for a high performance counter than this (other than a hardware solution from a plug-in card)?

  9. #9
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,184

    Re: [RESOLVED] CPU Clock Frequency

    Resolved.
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: http://codexpert.ro/blog/author/ovidiu-cucu/

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This a Codeguru.com survey!


On-Demand Webinars (sponsored)