Author Topic: Ran this program to get CPU speed but it exited abruptly  (Read 323 times)

0 Members and 1 Guest are viewing this topic.

KarenZ

  • Newbie
  • *
  • Posts: 44
Ran this program to get CPU speed but it exited abruptly
« on: March 08, 2018, 08:45:07 AM »
I was able to compile the following program without errors, however it just exited when run.
It is a program to get CPU speed,  it was working well in PowerBasic
could be something to do with QUAD?

Code: [Select]
$ filename "GetCpuSpeed_64.exe"
use rtl64
use minwin


' This program will obtain the  CPU's speed

Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As QUAD) As Long
Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As QUAD) As Long

'=====================================
FUNCTION CpuSpeed() AS STRING
 LOCAL Count0    AS QUAD
 LOCAL Count1    AS QUAD
 LOCAL Count2    AS QUAD
 LOCAL Freq      AS QUAD
 LOCAL NewCount  AS QUAD
 LOCAL CpuFreq   AS DWORD

 QueryPerformanceFrequency(Freq)
 Freq = Freq \ 10
 pushad
 db &h0f, &h31
 mov Count1[04], edx
 mov Count1[00], eax
 popad
 QueryPerformanceCounter(Count0)
 NewCount = Count0 + Freq
 WHILE (Count0 < NewCount)
   QueryPerformanceCounter(Count0)
 WEND
 pushad
 db &h0f, &h31
 mov Count2[04], edx
 mov Count2[00], eax
 popad
 CpuFreq = (Count2 - Count1) \ 100000
 IF CpuFreq > 1000 THEN
   FUNCTION =    str(CpuFreq / 1000 ) + " giga hertz"
 ELSE
   FUNCTION =   str(CpuFreq ) + " mega hertz"
 END IF

END FUNCTION



'====================
print CpuSpeed



The Powerbasic equivalent is here
Code: [Select]
#COMPILE EXE
#DIM ALL

 #INCLUDE "Win32API.inc"

'===============================
FUNCTION PBMAIN () AS LONG
      LOCAL cpuspd AS STRING
      cpuspd = CpuSpeed()
           ?  cpuspd

END FUNCTION



'=============================
FUNCTION CpuSpeed() AS STRING
 LOCAL Count0    AS QUAD
 LOCAL Count1    AS QUAD
 LOCAL Count2    AS QUAD
 LOCAL Freq      AS QUAD
 LOCAL NewCount  AS QUAD
 LOCAL CpuFreq   AS DWORD

 QueryPerformanceFrequency(Freq)
 Freq = Freq \ 10
 ASM pushad
 ASM db &h0f, &h31
 ASM mov Count1[04], edx
 ASM mov Count1[00], eax
 ASM popad
 QueryPerformanceCounter(Count0)
 NewCount = Count0 + Freq
 WHILE (Count0 < NewCount)
   QueryPerformanceCounter(Count0)
 WEND
 ASM pushad
 ASM db &h0f, &h31
 ASM mov Count2[04], edx
 ASM mov Count2[00], eax
 ASM popad
 CpuFreq = (Count2 - Count1) \ 100000
 IF CpuFreq > 1000 THEN
   FUNCTION = FORMAT$(CpuFreq / 1000, "0.000") & " giga hertz"
 ELSE
   FUNCTION = FORMAT$(CpuFreq, "0,0") & " mega hertz"
 END IF

END FUNCTION


Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 3696
    • Oxygen Basic
Re: Ran this program to get CPU speed but it exited abruptly
« Reply #1 on: March 08, 2018, 09:54:13 AM »
Karen,

The 64bit binary is now okay but my PC thinks the 32bit binary contains a virus :)

Code: [Select]
'2018-03-08 T 17:34:33
'64bit debug:
'convert to 64bit regs
'remove pushad and popad (invalid in 64bit mode)
'use rdi as pointer
'inhibit use of rdx register in 64bit mode

$ filename "GetCpuSpeed_64.exe"
use rtl64
use minwin


' This program will obtain the  CPU's speed

Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As QUAD) As Long
Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As QUAD) As Long

'=====================================
FUNCTION CpuSpeed() AS STRING
 LOCAL Count0    AS QUAD
 LOCAL Count1    AS QUAD
 LOCAL Count2    AS QUAD
 LOCAL Freq      AS QUAD
 LOCAL NewCount  AS QUAD
 LOCAL CpuFreq   AS DWORD

 QueryPerformanceFrequency(Freq)
 Freq = Freq \ 10
 db &h0f, &h31
 lea rdi,Count1
 #ifndef mode64bit
   mov [rdi+4], rdx
 #endif
 mov [rdi], rax
 QueryPerformanceCounter(Count0)
 NewCount = Count0 + Freq
 WHILE (Count0 < NewCount)
   QueryPerformanceCounter(Count0)
 WEND
 db &h0f, &h31
 lea rdi,Count2
 #ifndef mode64bit
   mov [rdi+4], rdx
 #endif
 mov [rdi], rax
 CpuFreq = (Count2 - Count1) \ 100000
 IF CpuFreq > 1000 THEN
   FUNCTION =    str(CpuFreq / 1000 ) + " giga hertz"
 ELSE
   FUNCTION =   str(CpuFreq ) + " mega hertz"
 END IF

END FUNCTION



'====================
print CpuSpeed

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1850
Re: Ran this program to get CPU speed but it exited abruptly
« Reply #2 on: March 08, 2018, 02:13:42 PM »
Code: [Select]
WHILE (Count0 < NewCount)
   QueryPerformanceCounter(Count0)
WEND

Is this how you're fighting SpeedStep, or what? :)
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, 2 x nVidia GTX 650Ti w/ 2GB VRAM, Windows 7 Ultimate Sp1)

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 3696
    • Oxygen Basic
Re: Ran this program to get CPU speed but it exited abruptly
« Reply #3 on: March 08, 2018, 11:49:15 PM »
It's a mystery to me. But it works on my PC.

incidentally, o2 assembler understands rdtsc

rdtsc 'db &h0f, &h31

ref:
https://en.wikipedia.org/wiki/Time_Stamp_Counter

My corrected update:

Code: [Select]
'2018-03-08 T 17:34:33
'https://en.wikipedia.org/wiki/Time_Stamp_Counter
'https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
'
'64bit debug:
'remove pushad and popad (invalid in 64bit mode)
'use rdi as pointer

$ filename "GetCpuSpeed_64.exe"
use rtl64
use minwin


' This program will obtain the  CPU's speed

Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As QUAD) As Long
Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As QUAD) As Long

'=====================================
FUNCTION CpuSpeed() AS STRING
 LOCAL Count0    AS QUAD
 LOCAL Count1    AS QUAD
 LOCAL Count2    AS QUAD
 LOCAL Freq      AS QUAD
 LOCAL NewCount  AS QUAD
 LOCAL CpuFreq   AS DWORD

 QueryPerformanceFrequency(Freq)
 Freq = Freq \ 10
 rdtsc 'db &h0f, &h31
 lea rdi,Count1
 mov [rdi+4], edx
 mov [rdi], eax
 QueryPerformanceCounter(Count0)
 NewCount = Count0 + Freq
 WHILE (Count0 < NewCount)
   QueryPerformanceCounter(Count0)
 WEND
 rdtsc 'db &h0f, &h31
 lea rdi,Count2
 mov [rdi+4], edx
 mov [rdi], eax
 CpuFreq = (Count2 - Count1) \ 100000
 IF CpuFreq > 1000 THEN
   FUNCTION =    str(CpuFreq / 1000 ) + " giga hertz"
 ELSE
   FUNCTION =   str(CpuFreq ) + " mega hertz"
 END IF

END FUNCTION



'====================
print CpuSpeed

KarenZ

  • Newbie
  • *
  • Posts: 44
Re: Ran this program to get CPU speed but it exited abruptly
« Reply #4 on: March 09, 2018, 05:07:08 AM »
Many Thanks Charles

Both posts' programs give the same figure when executed, however in the wikipedia in regards to rdtsc


https://en.wikipedia.org/wiki/Time_Stamp_Counter


Quote
On Windows platforms, Microsoft strongly discourages using the TSC for high-resolution timing for exactly these reasons, providing instead the Windows APIs QueryPerformanceCounter and QueryPerformanceFrequency.[2] On POSIX systems, a program can get similar function by reading the value of CLOCK_MONOTONIC clock using the clock_gettime function.[3

TSC is discourage so it is best that we stick to the program in post #2 ? What do you think?
Also did an antivirus scan on these programs and found no virus.

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 3696
    • Oxygen Basic
Re: Ran this program to get CPU speed but it exited abruptly
« Reply #5 on: March 09, 2018, 06:08:23 AM »
Hi Karen,

It will certainly simplify your code. All you need is QueryPerformanceFrequency:

Code: [Select]
Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As QUAD) As Long
quad q
QueryPerformanceFrequency q
print "CPU Clock Speed " str(q/1e6) " GHz"

PS:
Fortunately, we get far less virus false-positives with 64bit binaries.

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1850
Re: Ran this program to get CPU speed but it exited abruptly
« Reply #6 on: March 09, 2018, 06:40:02 AM »
Both programs are equally questionable under MS Windows. What PowerBASIC encodes as literal DB &H0f, &H31 because its parser can't recognize it as a valid CPU instruction, is in fact the RDTSC instruction supported by the O2 assembler officially.

Pure QueryPerformanceFrequency/QueryPerformanceCounter do not however guarantee that your measurements would not fall into a trap of SpeedStep -- Intel's technology to minimize CPU power consumption by lowering its speed when more or less idle, or of its AMD analog, Cool'n'Quiet.

SpeedStep can be very deceptive. See the upper picture attached below for three successive measurements taken on my former, slower CPU while writing a forum message. Now I'm working with Patrice Terrier on his 3D OBJ file viewer again and I need every bit of my new CPU's throughput for my OpenGL experimentation, so I have my CPU SpeedStep option disabled in my BIOS settings. (see lower picture below)
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, 2 x nVidia GTX 650Ti w/ 2GB VRAM, Windows 7 Ultimate Sp1)