CodeGuru Forums -
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic Newsletters VB Forums Developer.com


Newest CodeGuru.com Articles:

  • Installing SQL Server 2008
  • Writing UDFs for Firebird Embedded SQL Server
  • [Updated] Shutdown Manager
  • Building Windows Azure Cloud Service Applications with Azure Storage and the Azure SDK

  • Search CodeGuru:
     



    Go Back   CodeGuru Forums > Other Programming > Assembly
    FAQ Members List Calendar Search Today's Posts Mark Forums Read

    Assembly Questions and Answers for Assembly here!

    Reply
     
    Thread Tools Search this Thread Rating: Thread Rating: 1 votes, 5.00 average. Display Modes
      #1    
    Old August 22nd, 2004, 08:08 AM
    ovidiucucu's Avatar
    ovidiucucu ovidiucucu is offline
    Moderator/Reviewer
    Power Poster
     
    Join Date: Feb 2003
    Location: Iasi - Romania
    Posts: 6,518
    ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)
    [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 Cucu
    Reply With Quote
      #2    
    Old August 22nd, 2004, 04:17 PM
    indiocolifa's Avatar
    indiocolifa indiocolifa is offline
    Member +
     
    Join Date: Dec 2002
    Location: La Plata, Buenos Aires
    Posts: 604
    indiocolifa is on a distinguished road (30+)
    what do you mean with not exact?
    __________________
    Visit my page: http://usuarios.lycos.es/hernandp and my blog... http://hernandp.blogspot.com
    Reply With Quote
      #3    
    Old August 25th, 2004, 03:12 AM
    ovidiucucu's Avatar
    ovidiucucu ovidiucucu is offline
    Moderator/Reviewer
    Power Poster
     
    Join Date: Feb 2003
    Location: Iasi - Romania
    Posts: 6,518
    ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)
    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 Cucu
    Reply With Quote
      #4    
    Old September 9th, 2004, 03:42 AM
    marsh_pottaye marsh_pottaye is offline
    Member
     
    Join Date: Oct 2003
    Location: Romania
    Posts: 127
    marsh_pottaye will become famous soon enough (80+)
    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
    __________________
    VOTE HERE!
    Reply With Quote
      #5    
    Old September 9th, 2004, 08:19 AM
    ovidiucucu's Avatar
    ovidiucucu ovidiucucu is offline
    Moderator/Reviewer
    Power Poster
     
    Join Date: Feb 2003
    Location: Iasi - Romania
    Posts: 6,518
    ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)
    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 Cucu
    Reply With Quote
      #6    
    Old October 3rd, 2004, 10:17 PM
    janwas janwas is offline
    Junior Member
     
    Join Date: Oct 2004
    Posts: 1
    janwas is an unknown quantity at this point (<10)
    Re: CPU Clock Frequency

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

    HTH
    Reply With Quote
      #7    
    Old April 8th, 2005, 03:49 AM
    neolox neolox is offline
    Junior Member
     
    Join Date: Apr 2005
    Posts: 1
    neolox is an unknown quantity at this point (<10)
    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
    Reply With Quote
      #8    
    Old May 19th, 2005, 01:42 PM
    texasdiaz texasdiaz is offline
    Junior Member
     
    Join Date: May 2005
    Posts: 1
    texasdiaz is on a distinguished road (10+)
    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)?
    Reply With Quote
      #9    
    Old July 10th, 2005, 10:35 AM
    ovidiucucu's Avatar
    ovidiucucu ovidiucucu is offline
    Moderator/Reviewer
    Power Poster
     
    Join Date: Feb 2003
    Location: Iasi - Romania
    Posts: 6,518
    ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)ovidiucucu has a reputation beyond repute (3000+)
    Re: [RESOLVED] CPU Clock Frequency

    Resolved.
    __________________
    Ovidiu Cucu
    Reply With Quote
    Reply

    Bookmarks
    Go Back   CodeGuru Forums > Other Programming > Assembly


    Thread Tools Search this Thread
    Search this Thread:

    Advanced Search
    Display Modes Rate This Thread
    Rate This Thread:

    Posting Rules
    You may not post new threads
    You may not post replies
    You may not post attachments
    You may not edit your posts

    BB code is On
    Smilies are On
    [IMG] code is On
    HTML code is Off
    Forum Jump


    All times are GMT -5. The time now is 03:26 PM.



    Acceptable Use Policy

    internet.comMediabistrojusttechjobs.comGraphics.com

    WebMediaBrands Corporate Info


    Advertise | Newsletters | Feedback | Submit News

    Legal Notices | Licensing | Permissions | Privacy Policy


    Powered by vBulletin® Version 3.7.3
    Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
    Copyright WebMediaBrands Inc. 2002-2009