News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Quick CPU info based on CPUID

Started by jj2007, February 11, 2009, 11:27:32 AM

Previous topic - Next topic

jj2007

I know this is not new. Here is a little routine intended as a convenient way to tell each other which CPU we used to speed test an algo.

Usage:
call ShowCPU

Output:
Pentium 4 Prescott (2005+), MMX, SSE3

Full source with some references attached, for improvement. The usage of CPUID by various manufacturers seems a messy and sometimes hilarious story - see bottom of the source.


[attachment deleted by admin]

Mark Jones

Quote from: AMD XP 4400+ dual-core x64
Short version:
Pentium 4 (?), MMX, SSE3

Full version:
CPU family 15, model 11, Pentium 4 (?), MMX, SSE3
Step            1
Model           11
Family          15
Type            0
Ext model       6
Ext family      0
Manufacturer    AuthenticAMD
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

GregL

Quote from: Pentium D 940 dual-core x64Short version:
Pentium 4 (?), MMX, SSE3

Full version:
CPU family 15, model 6, Pentium 4 (?), MMX, SSE3
Step            4
Model           6
Family          15
Type            0
Ext model       0
Ext family      0
Manufacturer    GenuineIntel

jj2007

#3
Thanx. I have added these two, but I see it's getting more and more messy. Don't be surprised if you see an "AMD Pentium" :wink

There is a list at sandpile, but it is not so organised. One would really need a database to do it properly...

The executable can be run from the commandline as cpuid full or cpuid short. However, the main purpose is to include it into algos using TIMER.ASM, so that those who post timings don't have to bother about adding their CPU info.

EDIT: Attached an example with three applications:
1. CpuID shows how \masm32\include\CpuID.INC can be included in a simple program
2. StrCopy shows how the CPU info is displayed in a testbed
3. StrCopy also includes an algo (MbCopy) where the processor type is being used to decide whether the source or the destination data of a string copy should be pre-aligned. On an Intel Core, source alignment is over 10% faster; the opposite is true for a Pentium 4. I have not yet had a chance to test other CPUs - grateful for postings.

(note that \masm32\include\CpuID.INC is a hard-coded path)

EDIT(2): Updated with brand string, as suggested by evlncrn8

[attachment deleted by admin]

evlncrn8

to get the name, why not use the 0x8000002 cpuid ? :) (check using the 0x80000000 cpuid to see if its supported, if so, take the name from 0x80000002->0x80000004... problem solved

jj2007

Quote from: evlncrn8 on February 12, 2009, 10:59:16 AM
to get the name, why not use the 0x8000002 cpuid ? :) (check using the 0x80000000 cpuid to see if its supported, if so, take the name from 0x80000002->0x80000004... problem solved

Thanks, I had not yet discovered that one. Great feature - any idea since when it is supported for AMD's? Intel introduced it with the Pentium 4, apparently.

evlncrn8

think its been in since pentium 4 days, so i think anything within the last 6-8 years (possibly more) should do the job, if it returns nothing, just use your old code... 0x8000000 cpuid = amount of levels supported
if this is = 0 or < 80000004 then go with the old code, otherwise work from this new stuff :)

PBrennick

I am adding mine as it has not been listed yet and may be a help.

Quote
Short version:
Itanium 2 (2002+), MMX, SSE2

Full version:
CPU family 15, model 1, Itanium 2 (2002+), MMX, SSE2
Step            3
Model           1
Family          15
Type            0
Ext model       0
Ext family      0
Manufacturer    GenuineIntel

Paul
The GeneSys Project is available from:
The Repository or My crappy website

MichaelW

Both returns look correct, as far as they go. I'm not sure exactly what the 2000+ means, but I'm fairly certain that the CPU was fabricated not later than 1999.

Intel P3 (2000+), MMX, SSE1

Your CPU:
CPU family 6, model 7
Step            3
Model           7
Family          6
Type            0
Ext model       0
Ext family      0
Manufacturer    GenuineIntel
Description     Intel P3 (2000+), MMX, SSE1

eschew obfuscation

drizz

QuoteHere is a little routine intended as a convenient way to tell each other which CPU we used to speed test an algo.
What about not using CPUID? I mean it could save you a lot of time if you just use Registry to extract info.
Nice and small:
BasicInfo proc uses esi edi ebx
LOCAL hKey,nbr,rtype,freq,feat1,feat2
local procnamestr[64]:byte
LOCAL sysinfo:SYSTEM_INFO
LOCAL osver:OSVERSIONINFO
local featbuff[128]:byte

mov osver.dwOSVersionInfoSize,sizeof osver
invoke GetVersionEx,addr osver
invoke GetSystemInfo,addr sysinfo

invoke printf,T('OS        : Windows v%u.%u.%u %s',CRLF),osver.dwMajorVersion,osver.dwMinorVersion,osver.dwBuildNumber,addr osver.szCSDVersion
invoke printf,T('Processor : (%ux) '),sysinfo.dwNumberOfProcessors

invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,T("HARDWARE\DESCRIPTION\System\CentralProcessor\0"),0,KEY_ENUMERATE_SUB_KEYS or KEY_READ or KEY_QUERY_VALUE,addr hKey

mov nbr,sizeof procnamestr
mov rtype,REG_SZ
invoke RegQueryValueEx,hKey,T('ProcessorNameString'),0,addr rtype,addr procnamestr,addr nbr

mov nbr,sizeof DWORD
mov rtype,REG_DWORD
invoke RegQueryValueEx,hKey,T('~MHz'),0,addr rtype,addr freq,addr nbr

invoke RegCloseKey,hKey

invoke strcat,addr procnamestr,T(' ~ ')
invoke strlen,addr procnamestr
invoke _itoa,freq,addr procnamestr[eax],10
invoke strcat,addr procnamestr,T(' MHz',CRLF)

invoke printf,addr procnamestr

invoke strcpy,addr featbuff,T('[SSE :    ][SSE2:    ]')

mov eax,1
cpuid
lea ebx,featbuff
bt edx,25
; SET GLOBALS HERE:
; setc byte ptr YesNoCanDoSSE
sbb eax,eax
and eax,'SEY '-' ON '
add eax,' ON '
mov dword ptr featbuff[6],eax
bt edx,26
; setc byte ptr YesNoCanDoSSE2
sbb eax,eax
and eax,'SEY '-' ON '
add eax,' ON '
mov dword ptr featbuff[17],eax

invoke printf,T('Features  : %s'),addr featbuff

invoke puts,T(0)
ret
BasicInfo endp


mine:
OS        : Windows v5.1.2600 Service Pack 3
Processor : (1x) AMD Opteron(tm) Processor 148    ~ 2210 MHz
Features  : [SSE : YES][SSE2: YES]


yours:
Your CPU:
CPU family 15, model 7
Step            1
Model           7
Family          15
Type            0
Ext model       2
Ext family      0
Manufacturer    AuthenticAMD
Description     AMD AMD (?), MMX, SSE3

The truth cannot be learned ... it can only be recognized.

evlncrn8

Quote from: MichaelW on February 13, 2009, 07:14:37 PM
Both returns look correct, as far as they go. I'm not sure exactly what the 2000+ means, but I'm fairly certain that the CPU was fabricated not later than 1999.

the 2000+ is the speed in mhz that the chip is reporting :)

MichaelW

Quotethe 2000+ is the speed in mhz that the chip is reporting :)

I wish...it's clocked at 500MHz.
eschew obfuscation

jj2007

Here is the source of the "2000+" etc bits:

CPUID Family codes
* 486 (1989): family 4
* Pentium (1993): family 5
* Pentium Pro (1995): family 6, models 0 and 1
* Pentium 2 (1997): family 6, models 3, 5 and 6
* Pentium 3 (2000): family 6, models 7, 8, 10, 11
* Itanium (2001): family 7
* Pentium 4 (2000): family 15/0
* Itanium 2 (2002): family 15/1 and 15/2
* Pentium M (2003): family 6, models 9 and 13
* Core (2006): family 6, model 14
* Core 2 (2006): family 6, model 15 @

I have updated the algo, see above, it now has a short form:

Intel(R) Celeron(R) M CPU        420  @ 1.60GHz (SSE3)

The SSE level is in the global variable CpuSSE.

jj2007

Quote from: PBrennick on February 13, 2009, 06:25:16 PM
I am adding mine as it has not been listed yet and may be a help.

Thanks, Paul, and welcome back to the forum :thumbu

jj2007

Quote from: drizz on February 13, 2009, 07:23:48 PM
QuoteHere is a little routine intended as a convenient way to tell each other which CPU we used to speed test an algo.
What about not using CPUID? I mean it could save you a lot of time if you just use Registry to extract info.
Nice and small:
You are pulling my leg, drizz. But you are right, it could be a lot shorter. What really matters is the brand string
  mov esi, 80000002h
  mov edi, offset CpuBrand
  .Repeat
mov eax, esi
db 0Fh, 0A2h ; cpuid 80000002h-80000004h
stosd
mov eax, ebx
stosd
mov eax, ecx
stosd
mov eax, edx
stosd
inc esi
  .Until esi==80000005h


... and the SSE level in case you need to decide which branch to take in an algo:

  push 1
  pop eax
  db 0Fh, 0A2h ; cpuid 1
  mov CpuFlags, edx
  mov CpuExFlags, ecx
  and CpuMMX, 0
  and CpuSSE, 0
...
  mov edx, CpuFlags
  bt edx, 25
  jnc @F
  inc CpuSSE ; edx bit 25, SSE1
@@:

  bt edx, 26 ; edx bit 26, SSE2
  jnc @F
  inc CpuSSE
@@:

  mov ecx, CpuExFlags
  bt ecx, 0 ; ecx bit 0, SSE3
  jnc @F
  inc CpuSSE
@@:
  bt ecx, 9 ; ecx bit 9, SSE4
  jnc @F
  inc CpuSSE
@@: