Page 1 of 2

Posted: Sat Dec 30, 2006 8:24 pm
by Trond
First of all, you probably don't. Second, if you use the processor the speed may change.

This gives the correct result here, but it's not perfectly accurate.

Code: Select all

Procedure.q GetCycleCount()
  !rdtsc
  ProcedureReturn 
EndProcedure

Procedure CpuSpeed()
  Protected A.q
  Protected B.q
  A = GetCycleCount()
  Sleep_(100)
  B = GetCycleCount()
  ProcedureReturn (B-A) / 100000
EndProcedure

Debug CpuSpeed()
Obviously the longer you wait, the more accurate.

Posted: Mon Jan 01, 2007 4:15 pm
by TerryHough
@NoahPhense

Did you review topic
http://www.purebasic.fr/english/viewtopic.php?t=3811 ?

I hadn't looked at this since 2003, but the routine I use is based on the topic above and seems to be very consistent. (Jack's version)

For example, 20 sequential checks on this machine all indicate 1784 Mhz.

The registry reports 1785 Mhz, and the My Computer properties indicate 1.79 Ghz.

Posted: Mon Jan 01, 2007 4:37 pm
by netmaestro
This should be as accurate as any:

Code: Select all

Procedure GetCPUSpeed()
  QueryPerformanceFrequency_(@ulFreq.q) 
  ProcedureReturn ulFreq/1000000
EndProcedure

Debug GetCPUSpeed()

Posted: Mon Jan 01, 2007 6:49 pm
by akj
Netmaestro's code does not work on my 300MHz PC as it returns a value of 1.

Here's another routine that does work for me:

Code: Select all

Procedure.l CpuSpeed()
; Returns CPU speed in MHz
Protected A.q, B.q
!RDTSC
!MOV dword [p.v_A+4],Edx ; A hi
!MOV dword [p.v_A],Eax ; A lo
Sleep_(100)
!RDTSC
!MOV dword [p.v_B+4],Edx ; B hi
!MOV dword [p.v_B],Eax ; B lo
ProcedureReturn (B-A)/100000
EndProcedure

Posted: Mon Jan 01, 2007 6:57 pm
by netmaestro
Some older processors don't support QueryPerformanceFrequency, for those it won't work, true enough.

Posted: Tue Jan 02, 2007 3:07 am
by Azul
netmaestro wrote:Some older processors don't support QueryPerformanceFrequency, for those it won't work, true enough.
How new it should be?

I got '3' with AMD Athlon(tm) XP 2400+ (2GHz)

update: WinXP SP2

Posted: Tue Jan 02, 2007 3:19 am
by netmaestro
Not sure about specific hardware, which configurations support high-resolution frequency counters and which don't, but when you do:

Code: Select all

Result = QueryPerformanceFrequency_(@ulFreq.q)
if you find a non-zero value in Result, the high-resolution frequency counter is supported by your hardware, if it's zero your hardware doesn't support it. I'm not too strong in hardware, so the support for this could be coming from the motherboard / bios rather than the processor, I dunno. If somebody knows, a post would be appreciated.

Posted: Tue Jan 02, 2007 3:48 am
by CadeX
netmaestro wrote:Some older processors don't support QueryPerformanceFrequency, for those it won't work, true enough.
My processor is quite insulted by that, seeing as its an AMD 64bx2 2.2GHZ Core processor. Amd Hammer Family, That is not old.

I also get a "3" returned.

I did notice that everyone with issues of that code has an AMD.

Posted: Tue Jan 02, 2007 12:53 pm
by Derek
I got 1862 with my dual core core2 which runs at 1.86 per core, but as was mentioned, it's not an AMD.

Posted: Tue Jan 02, 2007 1:55 pm
by Flype
netmaestro wrote:Some older processors don't support QueryPerformanceFrequency, for those it won't work, true enough.
i have AMD AthlonXP 2800+ (2.08 Ghz) and QueryPerformanceFrequency returns here 3.

Posted: Tue Jan 02, 2007 2:32 pm
by rsts
Of those posted, Trond's give 1799 on my amd athlon 1.8 and NoahPhense
3600 or 3599.

Neither of the others seem to work properly. netmaestro returns the expected amd 3 and I get an assembler undefined symbol on akj's.

No complaints. just reporting my experience in the interest of science :)

cheers

Posted: Tue Jan 02, 2007 2:40 pm
by Derek
Tronds = 1862
NoahPhense = 3724
Akj = 2036
Netmaestro = 1862

So apart from Akj they all seem ok on intels.

Posted: Tue Jan 02, 2007 3:41 pm
by NoahPhense
Please keep in mind, that I'm working with a laptop processor. So, when
I put the laptop in Laptop/Portable mode, the processor drops to a
Dynamic 50%. Meaning that for all normal applications, a 2.16ghz dual
core processor will drop to 1.08ghz, meaning .54 ghz each core. (540).

Some other CPU apps on the net can see this. Even the windows built-in
perfmon.msc can see this. Even some of the code already posted here
has been able to detect this, in debug mode in PB. But after creating an
exe, it flys back to full power.

?

Code: Select all

Declare AppendFile(FileName.s, String.s)

Global Fn = 99

Enumeration 1
  #Window_frm_main
EndEnumeration
#WindowIndex=#PB_Compiler_EnumerationValue

Enumeration 1
  ;Window_frm_main
  #Gadget_frm_main_txt_main
EndEnumeration

#GadgetIndex=#PB_Compiler_EnumerationValue

Procedure.l Window_frm_main()
  If OpenWindow(#Window_frm_main,212,145,192,45,"CPU Speed Recorder",#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible)
    If CreateGadgetList(WindowID(#Window_frm_main))
      TextGadget(#Gadget_frm_main_txt_main,10,10,130,25,"DATA")
      SetGadgetFont(#Gadget_frm_main_txt_main,LoadFont(#Gadget_frm_main_txt_main,"@Arial Unicode MS",14,0))
      HideWindow(#Window_frm_main,0)
      ProcedureReturn WindowID(#Window_frm_main)
    EndIf
  EndIf
EndProcedure

Procedure.q GetCycleCount() 
  !rdtsc 
  ProcedureReturn 
EndProcedure 

Procedure CPUSPEED() 
  Protected A.q 
  Protected B.q 
  A = GetCycleCount() 
  Sleep_(100) 
  B = GetCycleCount() 
  ProcedureReturn (B-A) / 100000 
EndProcedure 

Procedure AppendFile(FileName.s, String.s) 
  If OpenFile(Fn, FileName) 
    FileSeek(Fn, Lof(Fn)) 
    WriteStringN(Fn, String) 
    CloseFile(Fn) 
  EndIf 
EndProcedure 

Procedure Tick() 
  dData.s = FormatDate("%hh:%ii:%ss", Date())
  cData.s = Str(CPUSPEED())
  finalData.s = dData + " - " + cData
  ; AppendFile("cpu.log", finalData)
  Debug finalData
  SetGadgetText(#Gadget_frm_main_txt_main, cData)
EndProcedure 

If Window_frm_main()

  quitfrm_main=0
  SetGadgetText(#Gadget_frm_main_txt_main, "**")
  SetTimer_(WindowID(#Window_frm_main), 1, 1000, @Tick())
  
  Repeat
    EventID  =WaitWindowEvent()
    MenuID   =EventMenu()
    GadgetID =EventGadget()
    WindowID =EventWindow()

    Select EventID
      Case #PB_Event_CloseWindow
        If WindowID=#Window_frm_main
          quitfrm_main=1
        EndIf

      Case #PB_Event_Gadget
        Select GadgetID
        EndSelect

    EndSelect
  Until quitfrm_main
  KillTimer_(WindowID(#Window_frm_main), 1)
  CloseWindow(#Window_frm_main)
EndIf

End
- np

Posted: Thu Jan 04, 2007 5:57 am
by Rescator
netmaestro it is a wonder your code is reliable at all.
That is the high performance crystal timing frequency and not related to MHz at all.
http://msdn.microsoft.com/library/defau ... ounter.asp

On my AMD the returned value of QueryPerformanceCounter Function is 3579545 and thus result in 3 after that divide.

Posted: Thu Jan 04, 2007 6:02 am
by netmaestro
Rescator, you misread the function call. You reference QueryPerformanceCounter, where my code uses QueryPerformanceFrequency:
MSDN wrote:QueryPerformanceFrequency Function

--------------------------------------------------------------------------------

The QueryPerformanceFrequency function retrieves the frequency of the high-resolution performance counter, if one exists. The frequency cannot change while the system is running.

Syntax

BOOL QueryPerformanceFrequency( LARGE_INTEGER *lpFrequency
);
Parameters

lpFrequency
[out] Pointer to a variable that receives the current performance-counter frequency, in counts per second. If the installed hardware does not support a high-resolution performance counter, this parameter can be zero.
which seems like it should work, and it does on all my machines. I don't know why it doesn't work on some machines, but I guess it's not too reliable.