Jump to content

_WinAPI_GetSystemInfo


Ascend4nt
 Share

Recommended Posts

Arrrgh :) , no, not really, re-read some code and I think

IF (CPUID(1).EBX[23:16] > 1)

is exactly what you are returning by this line

$iLogicalProcessorCount = BitAND(BitShift($iEBX, 16), 0xFF) ; 16-23

in your ASM example here. Returns 4 for all cores on my machine... re-reading the spec above it says "Hyper-Threading Technology or Core Multi-Processing (CMP) has been enabled", so 4 is a valid return. It's not possible to determine if the returned number of processor are full cores or HT-enabled ones by this means either... *sigh*, read also that it's best to let the OS handle the affinity, else you're only going to screw performance anyhow, but at this point I just see this as a pure hypothetical challenge ;) ...

Edit #1: Hey, Ascend4nt, you stole my 'Arrrgh' :) ...

Edit #2: Seems we're after slightly different things, a ) determine if a core is a 'Full' core and b ) how many physical processors are there on the mobo...

Edited by KaFu
Link to comment
Share on other sites

  • Replies 82
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

to tell you the truth, i'm not sure WHY I'm after this.. it just started out as a hypothetical.. and now I'm like godda*nit, I MUST know how to do this!!

And if what we're after is the same, I dunno. Yah, what I want is:

1. Physical CPU's count

2. # cores per each Physical CPU

3. Is Hyperthreading REALLY present *edit: ACTIVATED. hehe

The third is the most elusive and the one I want the most. But I'm so peeved at this whole project now :) sorry if I'm letting that frustration escape out into the thread.. but bah, humbug.. CPUID is just crap

But hey, on the plus side.. I learned something from trancexx, and messing with the Binary string output on the Assembly UDF. I've now got just pure hex code loading into Remote Execution buffers, and dang its fast, and cool. I didn't realize I missed my Assembly language programming days! You can do some awesome stuff, and superfast. The possibilities with this are endless! I'm thinking of what types of code we could boost other than the stuff that's already been done (embedded DLLS and Hash functions etc)..

Edited by Ascend4nt
Link to comment
Share on other sites

I'm gonna kill you...

wow my first death threat. Real productive :)

Anyway, you missed the entire post in response to your previous one, look back one page, here. Its complicated, not as simple as you put it in your post.

And @KaFu, my code isn't right just yet, it's trial and error. The Logical Processor count is going to only read from one physical cpu, so if there's more than one, you're gonna need to add it to the next cpu.. and then it's only logical, which can mean hyperthreaded and blablabla... argh i'm just tired :)

Link to comment
Share on other sites

Soooo... _WinAPI_SetProcessAffinityMask() returns the system mask as third parameter => number of detected cores. If I get it right, the result for CPUID is based on affinity. Maybe cycle through cores, read the "Processor Serial Number" as stated in the Intel docu (valid for AMD too?) to an array and sort that array? That should give you the number of physical processors + number of cores per physical processors. What's missing than is if the detected cores are full cores or HT-cores.

Link to comment
Share on other sites

wow my first death threat. Real productive :)

Anyway, you missed the entire post in response to your previous one, look back one page, here. Its complicated, not as simple as you put it in your post.

And @KaFu, my code isn't right just yet, it's trial and error. The Logical Processor count is going to only read from one physical cpu, so if there's more than one, you're gonna need to add it to the next cpu.. and then it's only logical, which can mean hyperthreaded and blablabla... argh i'm just tired :)

That was a joke.

And I didn't miss your post. I was reading what you linked.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Ok, said I'd finally get around to it...

Here's from my Core2Duo laptop:

PhysID Mask=000001FE, $PhysIDShift=1
APIC ID for Affinity 1:0
$iLog_ID value:0, $iPhys_ID value:0
APIC ID for Affinity 2:1
$iLog_ID value:1, $iPhys_ID value:0
@error = 0
# of Logical Processors:2
# Physical Processors:1
# Cores-per-Physical-Processor:2
Hyperthreading Status:HT is enabled

==========

Set Affinity to Core 1 result = True
Processor Get APIC ID for Core 1 from CPUID ASM string: 0xC7C0010000000FA2C1EB188BC3C3
Set Affinity to Core 2 result = True
Processor Get APIC ID for Core 2 from CPUID ASM string: 0xC7C0010000000FA2C1EB188BC3C3
Link to comment
Share on other sites

From my work computer:

HT de-activated:

PhysID Mask=000001FE, $PhysIDShift=1
APIC ID for Affinity 1:0
$iLog_ID value:0, $iPhys_ID value:0
@error = 0
# of Logical Processors:2
# Physical Processors:1
# Cores-per-Physical-Processor:1
Hyperthreading Status:HT is disabled, but supported

==========

Set Affinity to Core 1 result = True
Processor Get APIC ID for Core 1 from CPUID ASM string: 0xC7C0010000000FA2C1EB188BC3C3

HT activated:

PhysID Mask=000001FE, $PhysIDShift=1
APIC ID for Affinity 1:0
$iLog_ID value:0, $iPhys_ID value:0
APIC ID for Affinity 2:1
$iLog_ID value:1, $iPhys_ID value:0
@error = 0
# of Logical Processors:2
# Physical Processors:1
# Cores-per-Physical-Processor:1
Hyperthreading Status:HT is enabled

==========

Set Affinity to Core 1 result = True
Processor Get APIC ID for Core 1 from CPUID ASM string: 0xC7C0010000000FA2C1EB188BC3C3
Set Affinity to Core 2 result = True
Processor Get APIC ID for Core 2 from CPUID ASM string: 0xC7C0010000000FA2C1EB188BC3C3

This is promising. Ascend4nt's code correctly identifies the current enabled state of HT, but still can't differentiate between HT and multi-core processors (ie the Core2Duo).

Edited by wraithdu
Link to comment
Share on other sites

Soooo... _WinAPI_SetProcessAffinityMask() returns the system mask as third parameter => number of detected cores. If I get it right, the result for CPUID is based on affinity. Maybe cycle through cores, read the "Processor Serial Number" as stated in the Intel docu (valid for AMD too?) to an array and sort that array? That should give you the number of physical processors + number of cores per physical processors. What's missing than is if the detected cores are full cores or HT-cores.

Processor Serial # is disabled by default on most Intel CPU's, and I don't think even available for AMD CPU's. When that option became available years ago it caused quite a controversy and I think every Motherboard BIOS or whatnot since then has disabled that option by default.

The system Affinity mask, when all the bits are added up, should equal the number of processors reported by the O/S. And yeah, going through each one is what the basic idea is behind trying to figure out what that APIC value is and how it applies.. but there's more to it then just the APIC value from what I recall seeing in the newer cpucount program.. I mean, we're looking for *something* on each logical CPU we switch to in that loop.. but what it is that tells us its really a Hyperthread or not I'm not confident of just yet.

@wraithdu, thanks for continuing your tests... we might be making progress :)

*edit, wraithdu responded as I was typing, fixed my response!

Edited by Ascend4nt
Link to comment
Share on other sites

  • 2 weeks later...

..

Edited by Ascend4nt
Link to comment
Share on other sites

On my home box the results look fine ;)...

RemoteCodeExecCreate() successful! [Size=128] [ID=289110575428]
RemoteCodeExecCreate() successful! [Size=128] [ID=1129338184]
$iMaxLPPerCore=1
APIC ID for Affinity 1:0
  AffinityMask=1; Initial APIC=0; Physical ID=0; Core ID=0; SMT ID=0
APIC ID for Affinity 2:1
  AffinityMask=2; Initial APIC=1; Physical ID=0; Core ID=1; SMT ID=0
APIC ID for Affinity 4:2
  AffinityMask=4; Initial APIC=2; Physical ID=0; Core ID=2; SMT ID=0
APIC ID for Affinity 8:3
  AffinityMask=8; Initial APIC=3; Physical ID=0; Core ID=3; SMT ID=0
Time to execute _CPUID_GetCPUCount():6.85007481072325 ms
Return from _CPUID_GetCpuCount:
@error = 0
Total # of Logical Processors:4
Total # Physical Processors:1
Total Overall # Cores:4
Total # Cores per Physical Processor:4
Hyperthreading/Multicore Status: Multiple Core, Not HT-capable

Now the question what does a HT enabled CPU return... or what happens an AMD CPU's :)? Awesome code btw, will take me weeks to go through this one, we... you clearly left my field of expertise :) ...

Link to comment
Share on other sites

KaFu, alot of the code I'm still trying to figure out myself! I just decided to port what the C++ code was doing and replicate it with AutoIT (and Assembly).

As far as AMD CPU's - the function will give you an @error message because this only looks for the 'GenuineIntel' processor string. AMD CPU's require different techniques to get cores and physical processor counts, which looked pretty annoying. But since they don't have Hyperthreading capability, I decided I didn't want to deal with it. (much easier on the noggin :) )

Link to comment
Share on other sites

The result on my work-notebook is also okay :).

RemoteCodeExecCreate() successful! [Size=128] [ID=289110575428]
RemoteCodeExecCreate() successful! [Size=128] [ID=1129338184]
$iMaxLPPerCore=1
APIC ID for Affinity 1:0
  AffinityMask=1; Initial APIC=0; Physical ID=0; Core ID=0; SMT ID=0
APIC ID for Affinity 2:1
  AffinityMask=2; Initial APIC=1; Physical ID=0; Core ID=1; SMT ID=0
Time to execute _CPUID_GetCPUCount():20.9937296499974 ms
Return from _CPUID_GetCpuCount:
@error = 0
Total # of Logical Processors:2
Total # Physical Processors:1
Total Overall # Cores:2
Total # Cores per Physical Processor:2
Hyperthreading/Multicore Status: Multiple Core, Not HT-capable

As far as AMD CPU's - the function will give you an @error message because this only looks for the 'GenuineIntel' processor string. AMD CPU's require different techniques to get cores and physical processor counts, which looked pretty annoying. But since they don't have Hyperthreading capability, I decided I didn't want to deal with it. (much easier on the noggin :) )

So, why not use the 'old' code utilizing affinity for AMD processors? The main problem for Intel CPU was HT, so the old code should work fine for AMDs. This way you'll create a function for all CPUs, just use your new way for 'GenuineIntel' CPUs.
Link to comment
Share on other sites

So, why not use the 'old' code utilizing affinity for AMD processors? The main problem for Intel CPU was HT, so the old code should work fine for AMDs. This way you'll create a function for all CPUs, just use your new way for 'GenuineIntel' CPUs.

Counting cores in AMD processors and determining the # of physical processor 'packages' is a bit more confusing.. you have to determine if you should use one of 2 methods (legacy mode vs. new mode), then there's a possibility that (from AMD docs) there can be differing #'s of cores PER CPU package (1 core on 1 CPU, 3 cores on another, etc - though the O/S must 'equalize' them.. but then you will still get info from the processor with CPUID on what the total cores are for each one..).

You also have to go through the APIC enumeration, switching through each bit in the Affinity mask for all the processors and determining whats what... bah, why does Intel and AMD make this stuff so confusing?! I'd much rather just say there are 'x # of processors' based on _WinAPI_GetSystemInfo(6)' and be done with it :) . Maybe there's some AMD CPU Count code out there though, but all I've come across are people telling others to download utilities that are sometimes right, sometimes wrong. Check out this article and the first post, you'll see it's not working right.

Argh, I just read more info that certain CPUID capabilities can be disabled by the BIOS, thus botching the results of even the Intel CPU Count.. I'm gonna give up at this point I think. :)

Link to comment
Share on other sites

Here's my laptop (Core2Duo):

RemoteCodeExecCreate() successful! [Size=128] [ID=289110575428]
RemoteCodeExecCreate() successful! [Size=128] [ID=1129338184]
$iMaxLPPerCore=1
APIC ID for Affinity 1:0
  AffinityMask=1; Initial APIC=0; Physical ID=0; Core ID=0; SMT ID=0
APIC ID for Affinity 2:1
  AffinityMask=2; Initial APIC=1; Physical ID=0; Core ID=1; SMT ID=0
Time to execute _CPUID_GetCPUCount():5.79770309206725 ms
Return from _CPUID_GetCpuCount:
@error = 0
Total # of Logical Processors:2
Total # Physical Processors:1
Total Overall # Cores:2
Total # Cores per Physical Processor:2
Hyperthreading/Multicore Status: Multiple Core, Not HT-capable

I'll get my work computer stats next.

Link to comment
Share on other sites

Here ya go, first with HT off, then with HT on. This method seems to sniff out all the nuances. Good work!

RemoteCodeExecCreate() successful! [Size=128] [ID=289110575428]
RemoteCodeExecCreate() successful! [Size=128] [ID=1129338184]
$iMaxLPPerCore=2
APIC ID for Affinity 1:0
  AffinityMask=1; Initial APIC=0; Physical ID=0; Core ID=0; SMT ID=0
Time to execute _CPUID_GetCPUCount():3.76797403638915 ms
Return from _CPUID_GetCpuCount:
@error = 0
Total # of Logical Processors:1
Total # Physical Processors:1
Total Overall # Cores:1
Total # Cores per Physical Processor:1
Hyperthreading/Multicore Status: Single Core, HT is Disabled

==========

RemoteCodeExecCreate() successful! [Size=128] [ID=289110575428]
RemoteCodeExecCreate() successful! [Size=128] [ID=1129338184]
$iMaxLPPerCore=2
APIC ID for Affinity 1:0
  AffinityMask=1; Initial APIC=0; Physical ID=0; Core ID=0; SMT ID=0
APIC ID for Affinity 2:1
  AffinityMask=2; Initial APIC=1; Physical ID=0; Core ID=0; SMT ID=1
Time to execute _CPUID_GetCPUCount():52.0004084995473 ms
Return from _CPUID_GetCpuCount:
@error = 0
Total # of Logical Processors:2
Total # Physical Processors:1
Total Overall # Cores:1
Total # Cores per Physical Processor:1
Hyperthreading/Multicore Status: Single Core, HT is enabled
Link to comment
Share on other sites

Here ya go, first with HT off, then with HT on. This method seems to sniff out all the nuances. Good work!

wraithdu, thanks alot for testing things out. It's nice to know the code finally works right hehe.. I'm just annoyed that people can screw with the CPUID instruction in certain BIOS's so that the information I get won't be accurate. I doubt that'd be the case for most PC's though. I'd say, for now its 'good enough' for someone to detect if there's fake (Hyperthread) CPUs on the system in most scenarios.

One day I may think of reporting on that extra stuff, but I think for now this project is done! :)

Link to comment
Share on other sites

  • 3 weeks later...

Being pissed by one man, he decided to revenge to whole community... Almost all his posts that had a code are gone. I think this started from this topic.

As I understand it, he plans to make the code available again, he just wanted to relocate it to a third-party hoster to preserve his ability to change the code in anticipation of the upcoming ban...
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...