some CPU info

General FreeBASIC programming questions.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

some CPU info

Post by srvaldez »

this information might be useful if you need to know if certain instructions are supported by your CPU
for fbc-win-gcc-9.3

Code: Select all

extern "c"
	declare function __builtin_cpu_init () as long
	declare function __builtin_cpu_is (byval as const zstring ptr) as long
	declare function __builtin_cpu_supports (byval as const zstring ptr) as long
end extern

__builtin_cpu_init ()

if __builtin_cpu_is ("amd") then
    Print "AMD CPU."
end if
if __builtin_cpu_is ("intel") then
    Print "Intel CPU."
end if
if __builtin_cpu_is ("atom") then
    Print "Intel Atom CPU."
end if
if __builtin_cpu_is ("slm") then
    Print "supports Intel Silvermont CPU instructions."
end if
if __builtin_cpu_is ("core2") then
    Print "supports Intel Core 2 CPU instructions."
end if
if __builtin_cpu_is ("corei7") then
    Print "supports Intel Core i7 CPU instructions."
end if
if __builtin_cpu_is ("nehalem") then
    Print "supports Intel Core i7 Nehalem CPU instructions."
end if
if __builtin_cpu_is ("westmere") then
    Print "supports Intel Core i7 Westmere CPU instructions."
end if
if __builtin_cpu_is ("sandybridge") then
    Print "supports Intel Core i7 Sandy Bridge CPU instructions."
end if
if __builtin_cpu_is ("ivybridge") then
    Print "supports Intel Core i7 Ivy Bridge CPU instructions."
end if
if __builtin_cpu_is ("haswell") then
    Print "supports Intel Core i7 Haswell CPU instructions."
end if
if __builtin_cpu_is ("broadwell") then
    Print "supports Intel Core i7 Broadwell CPU instructions."
end if
if __builtin_cpu_is ("skylake") then
    Print "supports Intel Core i7 Skylake CPU instructions."
end if
if __builtin_cpu_is ("skylake-avx512") then
    Print "supports Intel Core i7 Skylake AVX512 CPU instructions."
end if
if __builtin_cpu_is ("cannonlake") then
    Print "supports Intel Core i7 Cannon Lake CPU instructions."
end if
if __builtin_cpu_is ("icelake-client") then
    Print "supports Intel Core i7 Ice Lake Client CPU instructions."
end if
if __builtin_cpu_is ("icelake-server") then
    Print "supports Intel Core i7 Ice Lake Server CPU instructions."
end if
if __builtin_cpu_is ("cascadelake") then
    Print "supports Intel Core i7 Cascadelake CPU instructions."
end if
/'
if __builtin_cpu_is ("tigerlake") then
    Print "supports Intel Core i7 Tigerlake CPU instructions."
end if
'/
if __builtin_cpu_is ("bonnell") then
    Print "supports Intel Atom Bonnell CPU instructions."
end if
if __builtin_cpu_is ("silvermont") then
    Print "supports Intel Atom Silvermont CPU instructions."
end if
if __builtin_cpu_is ("goldmont") then
    Print "supports Intel Atom Goldmont CPU instructions."
end if
if __builtin_cpu_is ("goldmont-plus") then
    Print "supports Intel Atom Goldmont Plus CPU instructions."
end if
if __builtin_cpu_is ("tremont") then
    Print "supports Intel Atom Tremont CPU instructions."
end if
if __builtin_cpu_is ("knl") then
    Print "supports Intel Knights Landing CPU instructions."
end if
if __builtin_cpu_is ("knm") then
    Print "supports Intel Knights Mill CPU instructions."
end if
if __builtin_cpu_is ("amdfam10h") then
    Print "supports AMD Family 10h CPU instructions."
end if
if __builtin_cpu_is ("barcelona") then
    Print "supports AMD Family 10h Barcelona CPU instructions."
end if
if __builtin_cpu_is ("shanghai") then
    Print "supports AMD Family 10h Shanghai CPU instructions."
end if
if __builtin_cpu_is ("istanbul") then
    Print "supports AMD Family 10h Istanbul CPU instructions."
end if
if __builtin_cpu_is ("btver1") then
    Print "supports AMD Family 14h CPU instructions."
end if
if __builtin_cpu_is ("amdfam15h") then
    Print "supports AMD Family 15h CPU instructions."
end if
if __builtin_cpu_is ("bdver1") then
    Print "supports AMD Family 15h Bulldozer version 1 instructions."
end if
if __builtin_cpu_is ("bdver2") then
    Print "supports AMD Family 15h Bulldozer version 2 instructions."
end if
if __builtin_cpu_is ("bdver3") then
    Print "supports AMD Family 15h Bulldozer version 3 instructions."
end if
if __builtin_cpu_is ("bdver4") then
    Print "supports AMD Family 15h Bulldozer version 4 instructions."
end if
if __builtin_cpu_is ("btver2") then
    Print "supports AMD Family 16h CPU instructions."
end if
if __builtin_cpu_is ("amdfam17h") then
    Print "supports AMD Family 17h CPU instructions."
end if
if __builtin_cpu_is ("znver1") then
    Print "supports AMD Family 17h Zen version 1 instructions."
end if
if __builtin_cpu_is ("znver2") then
    Print "supports AMD Family 17h Zen version 2 instructions."

end if 


if __builtin_cpu_supports ("cmov") then
    Print "supports the CMOV instruction." 
end if

if __builtin_cpu_supports ("mmx") then
    Print "supports the MMX instructions." 
end if

if __builtin_cpu_supports ("popcnt") then
    Print "supports the POPCNT instruction." 
end if

if __builtin_cpu_supports ("sse") then
    Print "supports the SSE instructions." 
end if

if __builtin_cpu_supports ("sse2") then
    Print "supports the SSE2 instructions." 
end if

if __builtin_cpu_supports ("sse3") then
    Print "supports the SSE3 instructions." 
end if

if __builtin_cpu_supports ("ssse3") then
    Print "supports the SSSE3 instructions." 
end if

if __builtin_cpu_supports ("sse4.1") then
    Print "supports the SSE4.1 instructions." 
end if

if __builtin_cpu_supports ("sse4.2") then
    Print "supports the SSE4.2 instructions." 
end if

if __builtin_cpu_supports ("avx") then
    Print "supports the AVX instructions." 
end if

if __builtin_cpu_supports ("avx2") then
    Print "supports the AVX2 instructions." 
end if

if __builtin_cpu_supports ("sse4a") then
    Print "supports the SSE4A instructions." 
end if

if __builtin_cpu_supports ("fma4") then
    Print "supports the FMA4 instructions." 
end if

if __builtin_cpu_supports ("xop") then
    Print "supports the XOP instructions." 
end if

if __builtin_cpu_supports ("fma") then
    Print "supports the FMA instructions." 
end if

if __builtin_cpu_supports ("avx512f") then
    Print "supports the AVX512F instructions." 
end if

if __builtin_cpu_supports ("bmi") then
    Print "supports the BMI instructions." 
end if

if __builtin_cpu_supports ("bmi2") then
    Print "supports the BMI2 instructions." 
end if

if __builtin_cpu_supports ("aes") then
    Print "supports the AES instructions." 
end if

if __builtin_cpu_supports ("pclmul") then
    Print "supports the PCLMUL instructions." 
end if

if __builtin_cpu_supports ("avx512vl") then
    Print "supports the AVX512VL instructions." 
end if

if __builtin_cpu_supports ("avx512bw") then
    Print "supports the AVX512BW instructions." 
end if

if __builtin_cpu_supports ("avx512dq") then
    Print "supports the AVX512DQ instructions." 
end if

if __builtin_cpu_supports ("avx512cd") then
    Print "supports the AVX512CD instructions." 
end if

if __builtin_cpu_supports ("avx512er") then
    Print "supports the AVX512ER instructions." 
end if

if __builtin_cpu_supports ("avx512pf") then
    Print "supports the AVX512PF instructions." 
end if

if __builtin_cpu_supports ("avx512vbmi") then
    Print "supports the AVX512VBMI instructions." 
end if

if __builtin_cpu_supports ("avx512ifma") then
    Print "supports the AVX512IFMA instructions." 
end if

if __builtin_cpu_supports ("avx5124vnniw") then
    Print "supports the AVX5124VNNIW instructions." 
end if

if __builtin_cpu_supports ("avx5124fmaps") then
    Print "supports the AVX5124FMAPS instructions." 
end if

if __builtin_cpu_supports ("avx512vpopcntdq") then
    Print "supports the AVX512VPOPCNTDQ instructions." 
end if

if __builtin_cpu_supports ("avx512vbmi2") then
    Print "supports the AVX512VBMI2 instructions." 
end if

if __builtin_cpu_supports ("gfni") then
    Print "supports the GFNI instructions." 
end if

if __builtin_cpu_supports ("vpclmulqdq") then
    Print "supports the VPCLMULQDQ instructions." 
end if

if __builtin_cpu_supports ("avx512vnni") then
    Print "supports the AVX512VNNI instructions." 
end if

if __builtin_cpu_supports ("avx512bitalg") then
    Print "supports the AVX512BITALG instructions." 
end if
Intel CPU.
supports Intel Core i7 CPU instructions.
supports Intel Core i7 Skylake CPU instructions.
supports the CMOV instruction.
supports the MMX instructions.
supports the POPCNT instruction.
supports the SSE instructions.
supports the SSE2 instructions.
supports the SSE3 instructions.
supports the SSSE3 instructions.
supports the SSE4.1 instructions.
supports the SSE4.2 instructions.
supports the AVX instructions.
supports the AVX2 instructions.
supports the FMA instructions.
supports the BMI instructions.
supports the BMI2 instructions.
supports the AES instructions.
supports the PCLMUL instructions.
Last edited by srvaldez on Sep 01, 2021 16:09, edited 1 time in total.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: some CPU info

Post by deltarho[1859] »

@srvaldez

I bet that took a while to write.

Of the 109 possible supports, my i7 Ivy Bridge only managed 12 which tells me that my CPU is now a bit long in the tooth. I knew that anyway, but it was interesting to see what it did not support.

Excellent! Image
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: some CPU info

Post by counting_pine »

Nice. Looks like it works for me on my decade-old Linux laptop (Intel T3100 CPU).
Intel CPU.
supports Intel Core 2 CPU instructions.
supports the CMOV instruction.
supports the MMX instructions.
supports the SSE instructions.
supports the SSE2 instructions.
supports the SSE3 instructions.
supports the SSSE3 instructions.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: some CPU info

Post by deltarho[1859] »

That is why I don't use POPCNT in my Hamming Weight method for seeding PRNGs. srvaldez has shown us a way with gcc's __builtin_popcount/ll. However, I have stayed with adeyblue's method because that works with gas as well.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: some CPU info

Post by deltarho[1859] »

Actually, mine isn't bad, but not as 'posh' as srvaldez's beast.
Intel CPU.
supports Intel Core i7 CPU instructions.
supports Intel Core i7 Ivy Bridge CPU instructions.
supports the CMOV instruction.
supports the MMX instructions.
supports the POPCNT instruction.
supports the SSE instructions.
supports the SSE2 instructions.
supports the SSE3 instructions.
supports the SSSE3 instructions.
supports the SSE4.1 instructions.
supports the SSE4.2 instructions.
supports the AVX instructions.
supports the AES instructions.
supports the PCLMUL instructions.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: some CPU info

Post by dodicat »

Here is a library popcount which works with -gen gas
libgcc.a, which is always loaded.

Code: Select all



declare function popcount64g cdecl alias "__popcountdi2"(as ulongint) as ulong '<---- library function, gas or gcc

randomize
Const u32max = &hFFFFFFFFul        
#define rnd64 (culngint(rnd*u32max)+(culngint(rnd*u32max) shl 32))


Function popcount64(x As Ulongint) As Ulong
      If x=18446744073709551615 Then Return 64
      x -= ((x Shr 1) And &h5555555555555555ull)
      x = (((x Shr 2) And &h3333333333333333ull) + (x And &h3333333333333333ull))
      x = (((x Shr 4) + x) And &hf0f0f0f0f0f0f0full)
      x += (x Shr 8)
      x += (x Shr 16)
      x+= (x Shr 32)
     return  x And &h0000003full
End function



for n as long=1 to 50
    dim as ulongint u=(rnd64)
    if n mod 2 then
print popcount64g(u),popcount64(u),"ulongint: ";u
else
  print popcount64g(culng(u)),popcount64(culng(u)),"ulong: ";culng(u)
end if
next
sleep 
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: some CPU info

Post by deltarho[1859] »

The library is blindingly fast, and we probably don't need anything faster.

Here s adeyblue's method

Code: Select all

Function popcount( x As Ulongint ) As Ulong
Dim As Ulong numBits
While x <> 0
  x = x And x - 1
  numBits += 1
Wend
Return numBits
End Function
which gives the same results but is four times faster than the library, if we need that speed.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: some CPU info

Post by srvaldez »

@deltarho[1859]
I like the simplicity of the code, my only gripe is in the parameter declaration, it does not explicitly state whether it's passed byval or byref
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: some CPU info

Post by dodicat »

Speed check (3 methods)

Code: Select all



declare function popcount64g cdecl alias "__popcountdi2"(as ulongint) as ulong '<---- library function, gas or gcc

randomize
Const u32max = &hFFFFFFFFul        
#define rnd64 (culngint(rnd*u32max)+(culngint(rnd*u32max) shl 32))


Function popcount64(x As Ulongint) As Ulong
      If x=18446744073709551615 Then Return 64
      x -= ((x Shr 1) And &h5555555555555555ull)
      x = (((x Shr 2) And &h3333333333333333ull) + (x And &h3333333333333333ull))
      x = (((x Shr 4) + x) And &hf0f0f0f0f0f0f0full)
      x += (x Shr 8)
      x += (x Shr 16)
      x+= (x Shr 32)
     return  x And &h0000003full
End function

Function popcount( x As Ulongint ) As Ulong
Dim As Ulong numBits
While x <> 0
  x = x And x - 1
  numBits += 1
Wend
Return numBits
End Function



dim as double t
dim as long lim
dim as ulongint ull
dim as long pc
lim=1000000

for k as long=1 to 5
randomize k
t=timer
for n as long=1 to lim
    ull=rnd64
    pc=popcount(ull)
    next n
    print timer-t,pc,"AdeyBlue"
    
    randomize k
  t=timer  
  for n as long=1 to lim
    ull=rnd64
    pc=popcount64g(ull)
    next n
    print timer-t,pc,"Libgcc.a"
    
  randomize k  
t=timer  
  for n as long=1 to lim
    ull=rnd64
    pc=popcount64(ull)
    next n
    print timer-t,pc,"dodicat"  
print
next k
sleep 
My results, 64 bit -O3

Code: Select all

 0.1171458000317216          31           AdeyBlue
 0.08046509989071637         31           Libgcc.a
 0.08063810004387051         31           dodicat

 0.1142390000168234          35           AdeyBlue
 0.08000000007450581         35           Libgcc.a
 0.07995360007043928         35           dodicat

 0.1149726000148803          34           AdeyBlue
 0.07924130000174046         34           Libgcc.a
 0.08154639997519553         34           dodicat

 0.1150817000307143          30           AdeyBlue
 0.08005829993635416         30           Libgcc.a
 0.08084379998035729         30           dodicat

 0.11385009996593            36           AdeyBlue
 0.07929999998304993         36           Libgcc.a
 0.08080220001284033         36           dodicat


 
Maybe my cpu

Code: Select all

Intel CPU.
supports Intel Core i7 CPU instructions.
supports Intel Core i7 Sandy Bridge CPU instructions.
supports the CMOV instruction.
supports the MMX instructions.
supports the POPCNT instruction.
supports the SSE instructions.
supports the SSE2 instructions.
supports the SSE3 instructions.
supports the SSSE3 instructions.
supports the SSE4.1 instructions.
supports the SSE4.2 instructions.
supports the AVX instructions.
supports the AES instructions.
supports the PCLMUL instructions.
Press any key to continue . . . 
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: some CPU info

Post by deltarho[1859] »

@srvaldez

ByVal is the default, as you know, which is what I want - I don't want x to change in the calling code. Some favour using ByVal even when not needed. I don't disagree with that - I just don't do it.

@dodicat
Maybe my cpu
No, my timing was at fault. Image

So, will I change my usage? Probably not - I'm only going past a population count a few times. Even with 1000 passes, I'd only save 37 microseconds.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: some CPU info

Post by deltarho[1859] »

Hmmm. I don't like your code, dodicat.

We don't need Randomize per 'k' loop - once is enough before the 'k' loop.

You also have 'ull=rnd64' being timed. That should be done just the once per 'k' loop.

You are in for a shock!
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: some CPU info

Post by dodicat »

OK deltarho[], I did that.
Now mine is quite fast in 64 bit -O3

Code: Select all

 0.01762470009271056         26           AdeyBlue
 0.003405599971301854        26           Libgcc.a
 1.00000761449337e-007       26           dodicat

 0.01953900000080466         29           AdeyBlue
 0.003250699955970049        29           Libgcc.a
 1.00000761449337e-007       29           dodicat

 0.03293280000798404         33           AdeyBlue
 0.003289000014774501        33           Libgcc.a
 2.00001522898674e-007       33           dodicat

 0.02267020009458065         30           AdeyBlue
 0.003238499979488552        30           Libgcc.a
 1.00000761449337e-007       30           dodicat

 0.0216814000159502          31           AdeyBlue
 0.003240399993956089        31           Libgcc.a
 1.00000761449337e-007       31           dodicat

 
But I wanted a bit of variety (different ulongints) in the loop, but no matter, It'll do.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: some CPU info

Post by deltarho[1859] »

dodicat wrote:Now mine is quite fast in 64 bit -O3
I would describe it as greased lightning. Image

It leaves the other two standing in 32-bit mode. It looks like it is doing a lot of work, but that is clearly not the case.

Interestingly, the library approach is the fastest with gas/gas64. It is remarkable what gcc does sometimes.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: some CPU info

Post by dodicat »

Don't be tricked, my method is short circuiting with -O3, probably because it is a straight command, albeit in steps.
AdeyBlue has a loop, which adds a degree of complication, and the libgcc.a has goodness knows what!
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: some CPU info

Post by deltarho[1859] »

dodicat wrote:AdeyBlue has a loop, which adds a degree of complication
Good point.

Unless we are testing an enormous number of population counts, the library method should do whether we use gas or gcc and in 32-bit or 64-bit mode - a popcount for all seasons and a good catch.
Post Reply