Jump to content

_WinAPI_GetSystemInfo


Ascend4nt
 Share

Recommended Posts

Here's the output from trancexxx's code on my dual-core laptop (no HT on this machine, so not sure why it's reporting that there is):

! EAX = 0
Return: 10
The highest basic calling parameter: 10
Vendor ID: GenuineIntel
! EAX = 1
Return: 1768
EAX: 1768
Hyper-Threading Technology: 1
ECX (feature flag): 49577
EBX (LogicalProcessorCount): 133120
+ Derived out of EAX:
    Stepping: 8
    BaseModel: 14
    BaseFamily: 6
    Reserved: 0
    Extended Model: 0
    Extended Family: 0
    Reserved: 0
+         Derived out of that:
               Model: ~~
               Family: ~~
+ Derived out of EBX:
    Brand ID: 0
    CLFLUSH size: 8
    LogicalProcessorCount: 2
    LocalApicId: 0
! EAX = 2
Return: 45330433
EAX: 45330433
EBX: 240
ECX: 0
EDX: 738472061
! EAX = 0x80000000
Return: 0x80000008
The highest extended calling parameter: 0x80000008
! EAX = 0x80000001
Return: 0x00000000
Extended feature flags EAX : 0
Extended feature flags EBX : 0
Extended feature flags ECX (CmpLegacy) : 0
Extended feature flags EDX: 1048576
! EAX = 0x80000002->0x80000003->0x80000004
Return: 808465202
Processor brand string: Genuine Intel(R) CPU           T2300  @ 1.66GHz
! EAX = 0x80000008
Return: 8224
EAX (largest virtual and physical address sizes): 8224
EBX: 0
ECX: 0
EDX: 0
ApicIdCoreIdSize = 0
Maximum number of cores 1

And the output from ascendant's:

CpuID availability:1
CPU Vendor ID from Reg: GenuineIntel
CPU Vendor ID from CPUID: GenuineIntel
HT bit set=True
# Logical Processors (if HT bit set):2
Cores-per-Package Available bit set=True
# Cores per Package (if above bit set):2

My work HT'ing machine coming later...

Link to comment
Share on other sites

  • Replies 82
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Ok, from my work HT'ing computer.

First with HT turned off (NUMBER_OF_PROCESSORS = 1):

CpuID availability:1
CPU Vendor ID from Reg: GenuineIntel
CPU Vendor ID from CPUID: GenuineIntel
HT bit set=True
# Logical Processors (if HT bit set):2
Cores-per-Package Available bit set=True
# Cores per Package (if above bit set):1
==========
! EAX = 0
Return: 5
The highest basic calling parameter: 5
Vendor ID: GenuineIntel
! EAX = 1
Return: 3914
EAX: 3914
Hyper-Threading Technology: 1
ECX (feature flag): 25757
EBX (LogicalProcessorCount): 133120
+ Derived out of EAX:
    Stepping: 10
    BaseModel: 4
    BaseFamily: 15
    Reserved: 0
    Extended Model: 0
    Extended Family: 0
    Reserved: 0
+         Derived out of that:
               Model: ~~
               Family: ~~
+ Derived out of EBX:
    Brand ID: 0
    CLFLUSH size: 8
    LogicalProcessorCount: 2
    LocalApicId: 0
! EAX = 2
Return: 1616596993
EAX: 1616596993
EBX: 0
ECX: 0
EDX: 8220736
! EAX = 0x80000000
Return: 0x80000008
The highest extended calling parameter: 0x80000008
! EAX = 0x80000001
Return: 0x00000000
Extended feature flags EAX : 0
Extended feature flags EBX : 0
Extended feature flags ECX (CmpLegacy) : 1
Extended feature flags EDX: 537919488
! EAX = 0x80000002->0x80000003->0x80000004
Return: 540287017
Processor brand string:               Intel(R) Pentium(R) 4 CPU 3.20GHz
! EAX = 0x80000008
Return: 12324
EAX (largest virtual and physical address sizes): 12324
EBX: 0
ECX: 0
EDX: 0
ApicIdCoreIdSize = 0
Maximum number of cores 1

Now with HT turned on (NUMBER_OF_PROCESSORS = 2):

CpuID availability:1
CPU Vendor ID from Reg: GenuineIntel
CPU Vendor ID from CPUID: GenuineIntel
HT bit set=True
# Logical Processors (if HT bit set):2
Cores-per-Package Available bit set=True
# Cores per Package (if above bit set):1
==========
! EAX = 0
Return: 5
The highest basic calling parameter: 5
Vendor ID: GenuineIntel
! EAX = 1
Return: 3914
EAX: 3914
Hyper-Threading Technology: 1
ECX (feature flag): 25757
EBX (LogicalProcessorCount): 133120
+ Derived out of EAX:
    Stepping: 10
    BaseModel: 4
    BaseFamily: 15
    Reserved: 0
    Extended Model: 0
    Extended Family: 0
    Reserved: 0
+         Derived out of that:
               Model: ~~
               Family: ~~
+ Derived out of EBX:
    Brand ID: 0
    CLFLUSH size: 8
    LogicalProcessorCount: 2
    LocalApicId: 0
! EAX = 2
Return: 1616596993
EAX: 1616596993
EBX: 0
ECX: 0
EDX: 8220736
! EAX = 0x80000000
Return: 0x80000008
The highest extended calling parameter: 0x80000008
! EAX = 0x80000001
Return: 0x00000000
Extended feature flags EAX : 0
Extended feature flags EBX : 0
Extended feature flags ECX (CmpLegacy) : 1
Extended feature flags EDX: 537919488
! EAX = 0x80000002->0x80000003->0x80000004
Return: 540287017
Processor brand string:               Intel(R) Pentium(R) 4 CPU 3.20GHz
! EAX = 0x80000008
Return: 12324
EAX (largest virtual and physical address sizes): 12324
EBX: 0
ECX: 0
EDX: 0
ApicIdCoreIdSize = 0
Maximum number of cores 1

Link to comment
Share on other sites

Ok, from my work HT'ing computer...

wraithdu, thanks for keeping at the testing. From what I've read, the Hyperthreading bit will be set regardless of whether it's enabled in the BIOS. It's just an indicator that it's 'available'. I don't recall reading anything to determine if its truly active.

However, the number of Cores-per-package is a good starting spot for determining the logical vs. physical. Not sure what would happen though on multiple-socket CPU's with/without multiple cores, but I'm sure we can figure something out.. (and I don't like the 'APIC' methods described by Intel.. quite confusing)

An algorithm can probably be easy to come up with to compare O/S-reported CPU's with the other reported values.

Now if I can figure out how the heck trancexx's code works and adopt it to my Intel CPUID instructions, we can ditch the Assembly UDF requirement...

Link to comment
Share on other sites

Problem is, both my results from the HT computer with HT turned on and off are exactly the same for both your tests...that is decisively NOT useful :)

The reported CPU's from the O/S was 1 with it off and 2 with it on, correct? That's what I was hinting at.. using that in combination with the reported information. We know by CPUID that there's only 1 core present on the processor. If the O/S reports more, then we have to figure something out with the logical CPU's.. at least, that's what I'm trying to figure out. I'll try to do some more digging though

Link to comment
Share on other sites

..

Edited by Ascend4nt
Link to comment
Share on other sites

I'm not sure if its possible to readjust a program's affinity mask to be able to work on all CPU's

That should be quiet easy doing something like this:

#include <WinAPI.au3>
Global Const $PROCESS_ALL_ACCESS = 0x1F0FFF
$hProc = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, @AutoItPID)
$aRet = _WinAPI_GetProcessAffinityMask($hProc)
$aRet = _WinAPI_SetProcessAffinityMask($hProc, $aRet[2])
ConsoleWrite('_WinAPI_SetProcessAffinityMask success = ' & $aRet & @crlf)

A quick test resulted in

@error = 0

# of Logical Processors:4

# Physical Processors:1

# Cores-per-Physical-Processor:4

Hyperthreading Status:HT is enabled

4 cores is true, but no HT on my machine though.

Edited by KaFu
Link to comment
Share on other sites

KaFu, thanks. I hadn't tried matching up affinity's myself, since the source code I based that function off of was from Intel, and I just assumed they knew best :)

Turns out that, at least in my tests, a call to 'equalize' the affinity does work (I put a pause in, adjusted the Affinity in Task Manager, had the function try to readjust it, checked Task Manager again - and it worked). So I just wound up changing one line (see *edit 2 remarks). Would admin rights be required? (I have them, so don't know offhand..)

Oh, and btw, _WinAPI_GetCurrentProcess() gives you $PROCESS_ALL_ACCESS by default.

And lastly, regarding the HT status - I really don't know whether to do a calculation (based on physical, cores-per-package and logical?) or to adjust something in the main code where it sets the HT status. What bugs me the most is that there's a variable assignment in the C code that's never used, and it's done on every run of the main loop..

Link to comment
Share on other sites

Would admin rights be required? (I have them, so don't know offhand..)

Don't know, have admin rights an all machines too.

Oh, and btw, _WinAPI_GetCurrentProcess() gives you $PROCESS_ALL_ACCESS by default.

I see, thanks for the hint.

regarding the HT status

Traced down how you do it (28bit), but sadly it gives me a True on all machines, though none is HT capable.

Reading the article here http://63.236.73.45/Intel/Article/26845 it might be possible to derive HT capability from the APIC ID (?). Under Heading "Association Between Physical and Logical Processors" it says

"With multicore systems, in order to detect HT Technology, we have to ensure that there must be more logical processor IDs with the same physical ID than the number of cores per physical processors."

I used the ASM code you provided, though it divers somehow from the one posted on that page.

Maybe someone with HT tests following and posts result:

#include <ASM.au3>
#include <WinAPI.au3>

$hCurrentProcess = _WinAPI_GetCurrentProcess()
$aArray = _WinAPI_GetProcessAffinityMask($hCurrentProcess)

Global $AsmObj = AsmInit()
For $i = 1 To Log($aArray[2] + 1) / Log(2)

    $bRet = _WinAPI_SetProcessAffinityMask($hCurrentProcess, 2^($i-1))
    ConsoleWrite("Set Affinity to Core " & $i & " result = " & $bRet & @crlf)

    ; http://63.236.73.45/Intel/Article/26845
    ; Association Between Physical and Logical Processors

    AsmReset($AsmObj)
    AsmAdd($AsmObj,"mov eax, 1")
    AsmAdd($AsmObj,"cpuid")
    AsmAdd($AsmObj,"shr ebx, 18")   ; shift bits right 24 (APIC ID is in bits 24-31, and now in bits 0-7 (0xFF)
    AsmAdd($AsmObj,"mov eax, ebx")
    AsmAdd($AsmObj,"ret")

    ConsoleWrite("Processor Get APIC ID for Core " & $i & " from CPUID ASM string: " & String(AsmGetBinary($AsmObj)) & @CRLF)

Next

AsmExit($AsmObj)

Exit

On my machine (1 proc, 2 cores, no HT) it results in:

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

KaFu, I don't understand why you post code thats the same that is in my program? Mine goes through each 'Affinity' iteration (for my 4-core CPU, thats 1, 2, 4, 8), gets the APIC ID and then reports that value through ConsoleWrite(). You should read my code sometime :)

Also, I've already explained the HT bit a few times before (its set for Hyperthreading OR multi-core capable systems), so thats why I told you that the APIC method was needed...

Anyway, don't mean to come off sounding rude, but I've already covered everything you just wrote.

I'll check the link though, thanks for that hehe

*edit: thats a link I posted in my resources, nm

Edited by Ascend4nt
Link to comment
Share on other sites

You should read my code sometime :)

I've done that, and as you noticed stole a lot (nearly all) of the code :) ...

Just wanted to point out that your above script reports Hyperthreading Status: HT is enabledon both my machines... which is not true... read you script and went off in deeper analysis of the APIC and hoped some HT user would post the results for my script above, to see the impact of HT on the APIC. For my multi-cores the APIC stays the same and I thought for HT cores there might be a change?

Link to comment
Share on other sites

I've done that, and as you noticed stole a lot (nearly all) of the code :) ...

Just wanted to point out that your above script reports Hyperthreading Status: HT is enabledon both my machines... which is not true... read you script and went off in deeper analysis of the APIC and hoped some HT user would post the results for my script above, to see the impact of HT on the APIC. For my multi-cores the APIC stays the same and I thought for HT cores there might be a change?

Well for one, you are printing out the assembly language binary string, which won't change. Secondly, my program ABOVE reports for each CPU in the affinity mask the APIC value (correctly). My output looks like this (4 core CPU):

APIC ID for Affinity 1:0

APIC ID for Affinity 2:1

APIC ID for Affinity 4:2

APIC ID for Affinity 8:3

And I did mention in the first paragraph in the script above that Hyperthreading will be reported as being enabled for multi-core systems too...

Link to comment
Share on other sites

And I did mention in the first paragraph in the script above that Hyperthreading will be reported as being enabled for multi-core systems too...

Oooookay... so what do you expect to be the returned result to identify HT? Thought it was the goal to ID HT cores :)...
Link to comment
Share on other sites

KaFu,

Yeah, the HT reported result by the function was wrong (again, based on Intel code), so I was trying to figure out if there was a different method, based on the counts we got for the 3 other variables. It seems easy enough - but I don't have any multi-processor pc access with/without Hyperthreading and with/without multiple cores.

HOWEVER! I did find and updated version of cpucount.cpp (if 2005 can be considered updated hehe). Anyway, that's a bit more complex and I'm currently not in the mood for complex. I think I'm gonna let that one sit for a while. C++ code isn't too hard to convert (being as I used to code in it), but *understanding* things can be painful on the noggin eh

Link to comment
Share on other sites

the HT reported result by the function was wrong... and I'm currently not in the mood for complex.

Puuh, feared I missed the point in your posts :), okay, let's set this one back for another time :)...
Link to comment
Share on other sites

I've gone through linked Intel's pdf (241618.pdf) and this topic again and I must say that I'm confused.

How do you know that HT info that you get is wrong? What HT info do you collect? Is the wrongness caused by the wrong expectations?

In that document there is a description of the procedure (and the results) and goes like this:

28 HTT Multi-Threading

The physical processor package is capable of

supporting more than one logical processor.

This field does not indicate that Hyper-Threading

Technology or Core Multi-Processing (CMP) has

been enabled for this specific processor. To

determine if Hyper-Threading Technology or CMP is

supported, compare value returned in EBX[23:16]

after executing CPUID with EAX=1. If the

resulting value is > 1, then the processor supports

Multi-Threading.

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

{

Multi-Threading = TRUE

}

ELSE

{

Multi-Threading = FALSE

}

What am I missing?
Link to comment
Share on other sites

Is the wrongness caused by the wrong expectations?

Yep, at least on my side, expected the bit to return HT capability, based on Title and what i read on some pages. But as you point out the info seems to be hidden here

IF (CPUID(1).EBX[23:16] > 1
Link to comment
Share on other sites

...

What am I missing?

argh.. okay.. lemme try to explain..

If bit 28 of EDX for CPUID(1) is set, it means either Hyperthreading or Multiple-cores-per=package, or BOTH

Bits 16-23 of EBX for CPUID(1) equate to logical processors available per package (on the CPU it is run from, I believe)

If CPUID(4) is available, then bits 26-31 are the # of cores per package (on the CPU it is run from again, I believe)

Now, if you have a Core i7, the O/S will report 8 CPU's. And I think CPUID will report you have 8 logical cores, 4 cores per package, and HT will be set regardless.

Now if somehow you have a motherboard that would support two i7's, then CPUID should give you the same information, 8 logical cores, 4 cores per package, and HT will be set. The O/S however will report 16 CPU's... so it's a tad bit confusin hey.

It seems like a simple division issue, but there's more to it than that.. HT can be turned off, but the CPUID will still report 8 logical cores, the O/S will report 4 CPU's, and 4 cores per package will still be reflected (along with HT bit being set regardless of whether its truly on or not - even in single-core chips)

So, if you can understand all that, you can understand why there's more confusion to the problem then we'd like.

I have two links for you that'll give you more confusion then that PDF. These are up to date:

Intel® 64 Architecture Processor Topology Enumeration (scroll down to the 1st diagram and start reading)

Here's the set of the latest Intel Architectures Software Developers Manuals. The CPUID instruction goes on for 30-somewhat pages (vol. 2a p.228-261), and its briefly explained in vol 3a (p.341..)

I'd post a link to the latest CPUCount.cpp program (version 2.somethin) but it took me a while to track it down (v1.4 was what I was initially using - which is no good)

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...