Jump to content

_WinAPI_GetSystemInfo


Ascend4nt
 Share

Recommended Posts

Ahh, I get what you guys are doing.. hey, here's another way to get the processor count, similar to wraithdu's

Yep, works fine too :) ...

I still don't think you'll see a difference for Hyperthreaded CPUs though - I believe its treated for nearly every API call, registry entry, and environment variable as one value and its not distinguished...

I think you have too! Otherwise, how should you utilize the _WinAPI_GetProcessAffinityMask() function (as it is based on the count of logical processors)? On my two systems (2+4 cores, not HT) the value is 2,2,0 and 4,4,0.... HT Users to the front! Go ahead and post your results.... pls :) ...
Link to comment
Share on other sites

  • Replies 82
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Damn, that's lame. On my work computer I got 2 for both physical and logical processors.

:) , but than there has to be something wrong with _WinAPI_GetSystemInfo(), 2 is what I would expect as response from _WinAPI_GetProcessAffinityMask(). Do you have access to the registry? You could check the number in

HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\

and in the cmd.exe shell

echo %NUMBER_OF_PROCESSORS%

If those return 2 as well... don't know :) . On my machine those values are 4 (4 cores, no HT).

Link to comment
Share on other sites

Looking at the registry entries... what are the 'Component Information' for both cores? (It's the only key with differences).

Mine contain a pattern like

CentralProcessor0 => 00 01

CentralProcessor1 => 01 02

CentralProcessor2 => 02 04

CentralProcessor3 => 03 08

Link to comment
Share on other sites

The Component Information looks like some kind of bit field. I have something like this -

CentralProcessor

-0

--Component Information = 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00

-1

--Component Information = 00 00 00 00 00 00 00 01 00 00 00 00 02 00 00 00

Link to comment
Share on other sites

--Component Information = 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00

Same pattern here... found a KB Entry saying that XP can't detect HT... the only other hint I found is, that you can extract a Hyperthreading flag from the CPUID, but the only way to extract that I saw was by WMI... which I want to avoid at all cost.
Link to comment
Share on other sites

Yeah, sorry to let you guys down, but I figured I'd let you find this info out for yourself. I've read numerous articles all across MSDN and the web stating that the API functions, the registry,and even those environment variables will give you a 'logical' CPU count. The only two sources, like I stated, are CPUID and the GetLogicalProcessorInformation API call (OS-restricted). From those, you can get the actual CPU's. But again, I'd need to see the output on the API call for a Hyperthreaded CPU to understand how it works exactly in order to get a usable reults from it.

I wonder if asking for a CPUID feature for AutoIT would be too much. I can imagine Valik immediately turning it down and insulting me and my stupidity etc, but I guess I should be used to it by now.

Link to comment
Share on other sites

I can imagine Valik immediately turning it down and insulting me and my stupidity etc, but I guess I should be used to it by now.

Welcome to the club :) ... let's see, what we can do about it...
Link to comment
Share on other sites

..

Edited by Ascend4nt
Link to comment
Share on other sites

Here's the output:

Window's GetLogicalProcessorInformation call Results:

Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #1

Processor Mask:00000003, Relationship:RelationProcessorPackage
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #2

Processor Mask:00000003, Relationship:RelationProcessorCore
Processor Core Flags:1
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #3

Processor Mask:00000003, Relationship:RelationCache
Cache Descriptor fields:
    Level:1, Associativity:8, (Cache) Line Size, in bytes:64, (Cache) Size, in bytes:16384, Cache type:CacheData
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #4

Processor Mask:00000003, Relationship:RelationCache
Cache Descriptor fields:
    Level:2, Associativity:8, (Cache) Line Size, in bytes:128, (Cache) Size, in bytes:2097152, Cache type:CacheUnified
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #5

Processor Mask:00000003, Relationship:RelationNumaNode
NumaNode Node Number:0
-------------------------------------------------------------
Link to comment
Share on other sites

wraithdu, thanks for the help!

So the information we need is definitely coming from the RelationProcessorCore Relationship structure. Here's what MSDN says about it:

RelationProcessorCore

The specified logical processors share a single processor core.

Now, since the mask on yours indicates 2 processors, we can see that they are definitely sharing one core. However, there's also information on MSDN which makes it even more frustrating to make that assumption for every O/S:

ProcessorCore

This structure contains valid data only if the Relationship member is RelationProcessorCore.

Flags

If the value of this member is 1, the logical processors identified by the value of the ProcessorMask member share functional units, as in Hyperthreading or SMT. Otherwise, the identified logical processors do not share functional units.

Windows Server 2003 and Windows XP Professional x64 Edition: This member is also 1 for cores that share a physical package. Therefore, to determine whether the processor supports multiple cores or hyperthreading on systems prior to Windows Vista, use the CPUID instruction.

The mask for all 4 of my processors never had a flag set to 1, so we know that mine don't share 'functional units' (I'm using XP x86). If this function was used on XP x64 or Server 2003, then we'd have to worry about what the heck 'physical package' is and how it differs from 'functional units'. Argh.. well at least we know a little more..

The fact that it still tells you to go with CPUID is just plain aggravating, as you need to do Assembly language to get that done, and that's just not something practical using AutoIt. Which is where it would be nice to have a built-in function. I think the developers would consider the addition of it as pointless though, as it is of limited use..

Anyway, thanks again. I suppose

Edited by ascendant
Link to comment
Share on other sites

I can do that. No problem.

edit:

Based on this document. (PDF 246 kB)

#include <Memory.au3>

; Allocating memory with $PAGE_EXECUTE_READWRITE
Global $pRemoteCode = _MemVirtualAlloc(0, 512, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)

; Standard allocation in reserved address
Global $tCodeBuffer = DllStructCreate("byte[512]", $pRemoteCode)


;XXXXXXXXXXXXXX BASIC CALLING PARAMETER XXXXXXXXXXXXXXXXXXXXXXXXXX

ConsoleWrite("! EAX = 0" & @CRLF)

; Buffer to fill with data:
Global $tBuffer = DllStructCreate("char[12]")

; Pointer to it:
$pBuffer = DllStructGetPtr($tBuffer)


; Code:
DllStructSetData($tCodeBuffer, 1, _
        "0x" & _
        "" & _; 10. SET eax AND CALL
        "B8" & SwapEndian(0) & _                                 ; mov eax, 0
        "0FA2" & _                                               ; cpuid
        "" & _ ; 20. ARRANGE DATA
        "891D" & SwapEndian($pBuffer) & _                        ; mov dword[$pBuffer], ebx
        "8915" & SwapEndian($pBuffer + 4) & _                    ; mov dword[$pBuffer + 4], edx
        "890D" & SwapEndian($pBuffer + 8) & _                    ; mov dword[$pBuffer + 8], ecx
        "" & _ ; 30. RETURN
        "C3" _
        )

; Execute it:
Global $aCall = DllCall("user32.dll", "dword", "CallWindowProcW", _
        "ptr", $pRemoteCode, _
        "int", 0, _
        "int", 0, _
        "int", 0, _
        "int", 0)

; Return:
ConsoleWrite("Return: " & $aCall[0] & @CRLF)

; Collected data:

ConsoleWrite("The highest basic calling parameter: " & $aCall[0] & @CRLF)
ConsoleWrite("Vendor ID: " & DllStructGetData($tBuffer, 1) & @CRLF)

ConsoleWrite(@CRLF & @CRLF)
ConsoleWrite("! EAX = 1" & @CRLF)

; New buffer:
$tBuffer = DllStructCreate("dword[4]")

; Pointer to it:
$pBuffer = DllStructGetPtr($tBuffer)

DllStructSetData($tCodeBuffer, 1, _
        "0x" & _
        "" & _ ; 10. SET eax AND CALL
        "B8" & SwapEndian(1) & _                                 ; mov eax, 1
        "0FA2" & _                                               ; cpuid
        "" & _ ; 20. ARRANGE DATA
        "A3" & SwapEndian($pBuffer) & _                          ; mov dword[$pBuffer], eax
        "8915" & SwapEndian($pBuffer + 4) & _                    ; mov dword[$pBuffer + 4], edx
        "890D" & SwapEndian($pBuffer + 8) & _                    ; mov dword[$pBuffer + 8], ecx
        "891D" & SwapEndian($pBuffer + 12) & _                   ; mov dword[$pBuffer + 12], ebx
        "" & _ ; 30. RETURN
        "C3" _
        )

; Execute it:
$aCall = DllCall("user32.dll", "dword", "CallWindowProcW", _
        "ptr", $pRemoteCode, _
        "int", 0, _
        "int", 0, _
        "int", 0, _
        "int", 0)

; Return eax:
ConsoleWrite("Return: " & $aCall[0] & @CRLF)

; Collected data:
ConsoleWrite("EAX: " & DllStructGetData($tBuffer, 1, 1) & @CRLF)
ConsoleWrite("Hyper-Threading Technology: " & BitAND(BitShift(DllStructGetData($tBuffer, 1, 2), 28), 1) & @CRLF) ; bit 28
ConsoleWrite("ECX (feature flag): " & DllStructGetData($tBuffer, 1, 3) & @CRLF)
ConsoleWrite("EBX (LogicalProcessorCount): " & DllStructGetData($tBuffer, 1, 4) & @CRLF)

ConsoleWrite("+ Derived out of EAX: " & @CRLF)
$iEAX = DllStructGetData($tBuffer, 1, 1)

$iStepping = BitAND($iEAX, 0xF) ; 0-3
ConsoleWrite("    Stepping: " & $iStepping & @CRLF)
$iBaseModel = BitAND(BitShift($iEAX, 4), 0xF) ; 4-7
ConsoleWrite("    BaseModel: " & $iBaseModel & @CRLF)
$iBaseFamily = BitAND(BitShift($iEAX, 8), 0xF) ; 8-11
ConsoleWrite("    BaseFamily: " & $iBaseFamily & @CRLF)
ConsoleWrite("    Reserved: " & BitAND(BitShift($iEAX, 12), 0xF) & @CRLF) ; 12-15
$iExtendedModel = BitAND(BitShift($iEAX, 16), 0xF) ; 16-19
ConsoleWrite("    Extended Model: " & $iExtendedModel & @CRLF)
$iExtendedFamily = BitAND(BitShift($iEAX, 20), 0xFF) ; 20-27
ConsoleWrite("    Extended Family: " & $iExtendedFamily & @CRLF)
ConsoleWrite("    Reserved: " & BitAND(BitShift($iEAX, 28), 0xF) & @CRLF) ; 28-31

ConsoleWrite("+         Derived out of that: " & @CRLF)
ConsoleWrite("               Model: " & "~~" & @CRLF) ;<- needs calculating
ConsoleWrite("               Family: " & "~~" & @CRLF) ;<- needs calculating


ConsoleWrite("+ Derived out of EBX: " & @CRLF)
$iEBX = DllStructGetData($tBuffer, 1, 4)
$iBrandID = BitAND($iEBX, 0xFF) ; 0-7
ConsoleWrite("    Brand ID: " & $iBrandID & @CRLF)
$iCLFLUSH = BitAND(BitShift($iEBX, 8), 0xFF) ; 8-15
ConsoleWrite("    CLFLUSH size: " & $iCLFLUSH & @CRLF)
$iLogicalProcessorCount = BitAND(BitShift($iEBX, 16), 0xFF) ; 16-23
ConsoleWrite("    LogicalProcessorCount: " & $iLogicalProcessorCount & @CRLF)
$LocalApicId =  BitAND(BitShift($iEBX, 24), 0xFF) ; 24-32
ConsoleWrite("    LocalApicId: " & $LocalApicId & @CRLF)






ConsoleWrite(@CRLF & @CRLF)
ConsoleWrite("! EAX = 2" & @CRLF); This one is couldn't be tested with me (the highest basic calling parameter returned 1)

; New buffer:
$tBuffer = DllStructCreate("dword[4]")

; Pointer to it:
$pBuffer = DllStructGetPtr($tBuffer)

DllStructSetData($tCodeBuffer, 1, _
        "0x" & _
        "" & _ ; 10. SET eax AND CALL
        "B8" & SwapEndian(2) & _                                 ; mov eax, 2
        "0FA2" & _                                               ; cpuid
        "" & _ ; 20. ARRANGE DATA
        "A3" & SwapEndian($pBuffer) & _                          ; mov dword[$pBuffer], eax
        "891D" & SwapEndian($pBuffer + 4) & _                    ; mov dword[$pBuffer + 4], ebx
        "890D" & SwapEndian($pBuffer + 8) & _                    ; mov dword[$pBuffer + 8], ecx
        "8915" & SwapEndian($pBuffer + 12) & _                   ; mov dword[$pBuffer + 12], edx
        "" & _ ; 30. RETURN
        "C3" _
        )

; Execute it:
$aCall = DllCall("user32.dll", "dword", "CallWindowProcW", _
        "ptr", $pRemoteCode, _
        "int", 0, _
        "int", 0, _
        "int", 0, _
        "int", 0)

; Return eax:
ConsoleWrite("Return: " & $aCall[0] & @CRLF)

; Collected data:
ConsoleWrite("EAX: " & DllStructGetData($tBuffer, 1, 1) & @CRLF)
ConsoleWrite("EBX: " & DllStructGetData($tBuffer, 1, 2) & @CRLF)
ConsoleWrite("ECX: " & DllStructGetData($tBuffer, 1, 3) & @CRLF)
ConsoleWrite("EDX: " & DllStructGetData($tBuffer, 1, 4) & @CRLF)



; ...etc, depending on he highest basic calling parameter




;XXXXXXXXXXXXXX EXTENDED CALLING PARAMETER XXXXXXXXXXXXXXXXXXXXXXXXXX


ConsoleWrite(@CRLF & @CRLF)
ConsoleWrite("! EAX = 0x80000000" & @CRLF)

; New buffer:
$tBuffer = DllStructCreate("dword[4]")

; Pointer to it:
$pBuffer = DllStructGetPtr($tBuffer)

DllStructSetData($tCodeBuffer, 1, _
        "0x" & _
        "" & _ ; 10. SET eax AND CALL
        "B8" & SwapEndian(0x80000000) & _                        ; mov eax, 0x80000000
        "0FA2" & _                                               ; cpuid
        "" & _ ; 20. ARRANGE DATA
        "A3" & SwapEndian($pBuffer) & _                          ; mov dword[$pBuffer], eax
        "" & _ ; 30. RETURN
        "C3" _
        )

; Execute it:
$aCall = DllCall("user32.dll", "ptr", "CallWindowProcW", _
        "ptr", $pRemoteCode, _
        "int", 0, _
        "int", 0, _
        "int", 0, _
        "int", 0)

; Return eax:
ConsoleWrite("Return: " & $aCall[0] & @CRLF)

; Collected data:
ConsoleWrite("The highest extended calling parameter: " & Ptr(DllStructGetData($tBuffer, 1, 1)) & @CRLF)


ConsoleWrite(@CRLF & @CRLF)
ConsoleWrite("! EAX = 0x80000001" & @CRLF)

; New buffer:
$tBuffer = DllStructCreate("dword[4]")

; Pointer to it:
$pBuffer = DllStructGetPtr($tBuffer)

DllStructSetData($tCodeBuffer, 1, _
        "0x" & _
        "" & _ ; 10. SET eax AND CALL
        "B8" & SwapEndian(0x80000001) & _                        ; mov eax, 0x80000001
        "0FA2" & _                                               ; cpuid
        "" & _ ; 20. ARRANGE DATA
        "A3" & SwapEndian($pBuffer) & _                          ; mov dword[$pBuffer], eax
        "891D" & SwapEndian($pBuffer + 4) & _                    ; mov dword[$pBuffer + 4], ebx
        "890D" & SwapEndian($pBuffer + 8) & _                    ; mov dword[$pBuffer + 8], ecx
        "8915" & SwapEndian($pBuffer + 12) & _                   ; mov dword[$pBuffer + 12], edx
        "" & _ ; 30. RETURN
        "C3" _
        )

; Execute it:
Local $aCall = DllCall("user32.dll", "ptr", "CallWindowProcW", _
        "ptr", $pRemoteCode, _
        "int", 0, _
        "int", 0, _
        "int", 0, _
        "int", 0)

; Return eax:
ConsoleWrite("Return: " & $aCall[0] & @CRLF)

; Collected data:
ConsoleWrite("Extended feature flags EAX : " & DllStructGetData($tBuffer, 1, 1) & @CRLF)
ConsoleWrite("Extended feature flags EBX : " & DllStructGetData($tBuffer, 1, 2) & @CRLF)
ConsoleWrite("Extended feature flags ECX (CmpLegacy) : " & DllStructGetData($tBuffer, 1, 3) & @CRLF)
ConsoleWrite("Extended feature flags EDX: " & DllStructGetData($tBuffer, 1, 4) & @CRLF)


ConsoleWrite(@CRLF & @CRLF)
ConsoleWrite("! EAX = 0x80000002->0x80000003->0x80000004" & @CRLF)

; New buffer:
$tBuffer = DllStructCreate("char[48]")

; Pointer to it:
$pBuffer = DllStructGetPtr($tBuffer)

DllStructSetData($tCodeBuffer, 1, _
        "0x" & _
        "" & _ ; 10. SET eax AND CALL
        "B8" & SwapEndian(0x80000002) & _                        ; mov eax, 0x80000002
        "0FA2" & _                                               ; cpuid
        "" & _ ; 20. ARRANGE DATA
        "A3" & SwapEndian($pBuffer) & _                          ; mov dword[$pBuffer], eax
        "891D" & SwapEndian($pBuffer + 4) & _                    ; mov dword[$pBuffer + 4], ebx
        "890D" & SwapEndian($pBuffer + 8) & _                    ; mov dword[$pBuffer + 8], ecx
        "8915" & SwapEndian($pBuffer + 12) & _                   ; mov dword[$pBuffer + 12], edx
        "" & _ ; 30. SET eax AND CALL
        "B8" & SwapEndian(0x80000003) & _                        ; mov eax, 0x80000003
        "0FA2" & _                                               ; cpuid
        "" & _ ; 40. ARRANGE DATA
        "A3" & SwapEndian($pBuffer + 16) & _                     ; mov dword[$pBuffer + 16], eax
        "891D" & SwapEndian($pBuffer + 20) & _                   ; mov dword[$pBuffer + 20], ebx
        "890D" & SwapEndian($pBuffer + 24) & _                   ; mov dword[$pBuffer + 24], ecx
        "8915" & SwapEndian($pBuffer + 28) & _                   ; mov dword[$pBuffer + 28], edx
        "" & _ ; 50. SET eax AND CALL
        "B8" & SwapEndian(0x80000004) & _                        ; mov eax, 0x80000004
        "0FA2" & _                                               ; cpuid
        "" & _ ; 60. ARRANGE DATA
        "A3" & SwapEndian($pBuffer + 32) & _                     ; mov dword[$pBuffer + 32], eax
        "891D" & SwapEndian($pBuffer + 36) & _                   ; mov dword[$pBuffer + 36], ebx
        "890D" & SwapEndian($pBuffer + 40) & _                   ; mov dword[$pBuffer + 40], ecx
        "8915" & SwapEndian($pBuffer + 44) & _                   ; mov dword[$pBuffer + 44], edx
        "" & _ ; 70. RETURN
        "C3" _
        )

; Execute it:
$aCall = DllCall("user32.dll", "int", "CallWindowProcW", _
        "ptr", $pRemoteCode, _
        "int", 0, _
        "int", 0, _
        "int", 0, _
        "int", 0)

; Return eax:
ConsoleWrite("Return: " & $aCall[0] & @CRLF)

; Collected data:
ConsoleWrite("Processor brand string: " & DllStructGetData($tBuffer, 1) & @CRLF)





; And so on...

; Just one more:
ConsoleWrite(@CRLF & @CRLF)
ConsoleWrite("! EAX = 0x80000008" & @CRLF)

; New buffer:
$tBuffer = DllStructCreate("dword[4]")

; Pointer to it:
$pBuffer = DllStructGetPtr($tBuffer)

DllStructSetData($tCodeBuffer, 1, _
        "0x" & _
        "" & _ ; 10. SET eax AND CALL
        "B8" & SwapEndian(0x80000008) & _                        ; mov eax, 0x80000008
        "0FA2" & _                                               ; cpuid
        "" & _ ; 20. ARRANGE DATA
        "A3" & SwapEndian($pBuffer) & _                          ; mov dword[$pBuffer], eax
        "891D" & SwapEndian($pBuffer + 4) & _                    ; mov dword[$pBuffer + 4], ebx
        "890D" & SwapEndian($pBuffer + 8) & _                    ; mov dword[$pBuffer + 8], ecx
        "8915" & SwapEndian($pBuffer + 12) & _                   ; mov dword[$pBuffer + 12], edx
        "" & _ ; 30. RETURN
        "C3" _
        )

; Execute it:
$aCall = DllCall("user32.dll", "dword", "CallWindowProcW", _
        "ptr", $pRemoteCode, _
        "int", 0, _
        "int", 0, _
        "int", 0, _
        "int", 0)

; Return eax:
ConsoleWrite("Return: " & $aCall[0] & @CRLF)

; Collected data:
ConsoleWrite("EAX (largest virtual and physical address sizes): " & DllStructGetData($tBuffer, 1, 1) & @CRLF)
ConsoleWrite("EBX: " & DllStructGetData($tBuffer, 1, 2) & @CRLF)
ConsoleWrite("ECX: " & DllStructGetData($tBuffer, 1, 3) & @CRLF)
ConsoleWrite("EDX: " & DllStructGetData($tBuffer, 1, 4) & @CRLF)

; Maximum number of cores
$iApicIdCoreIdSize = BitAND(DllStructGetData($tBuffer, 1, 3), 0xF) ; 0-3 ECX
ConsoleWrite("ApicIdCoreIdSize = " & $iApicIdCoreIdSize & @CRLF)
If $iApicIdCoreIdSize = 0 Then
    $IMNC = 1
Else
    $IMNC = 2 ^ $iApicIdCoreIdSize
EndIf
ConsoleWrite("Maximum number of cores " & $IMNC & @CRLF)





; Used function:
Func SwapEndian($iValue)
    Return Hex(BinaryMid($iValue, 1, 4))
EndFunc   ;==>SwapEndian

Read section 3 in that document to properly interpret collected data. I wasn't deep enough.

I wonder will forum go down again and this lost. Will see.

Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

@trancexx, this might save you some time.. you can recode the Assembly into a DLL or whatnot if you like, but anyway, I decided to go ahead and use the AutoIt Inline Assembly UDF, and came up with some code (work-in-progress, just reports findings right now):

@wraithdu, if you'd be so kind as to run this also at work? It writes some info to the Console, but the main part pops up in a MsgBox. You need the zip file from the AutoIt Inline Assembly UDF in the same folder.

*Edit: see the new version further below

Edited by ascendant
Link to comment
Share on other sites

I can do that. No problem.

It's a kind of magic I didn't master :) ... and probably will never do ;) ... one question though, I think we're mainly after the Hyperthreading bit (at least what I understood :) ), and I read it's the 28 bit in EDX, so shouldn't this line

ConsoleWrite("Hyper-Threading Technology: " & BitAND(BitShift(DllStructGetData($tBuffer, 1, 2), 28), 1) & @CRLF) ; bit 28

be more like this?

ConsoleWrite("Hyper-Threading Technology: " & BitAND(BitShift(DllStructGetData($tBuffer, 1, 4), 28), 1) & @CRLF) ; bit 28
The first returned 1 for me, the second 0, and as far as I know this computer doesn't have HT enabled... Great Work!
Link to comment
Share on other sites

@trancexx, Awesome tricks to get Assembly code working! The AMD techniques for getting CPUID though is AMD-specific, at least to a point. (check out the 'Resources' in my UDF for more info).

@KaFu: The Hyperthreading bit returned from CPUID is set on my computer too. Check out that tool I linked to (the CPUID Explorer), zip file mvp_tips-CPUID-CPUID-Release-CPUID.exe

What I learned (and put in my notes in my UDF) is that the Hyperthreading bit (from CPUID) can also mean multiple-cores-per-package. That's why more info is needed. My approach is different than trancexx's, but it should return the information we are looking for for Intel Processors. AMD doesn't have Hyperthreading yet, so all their CPU's are 'real' (though I don't care about detecting individual cores).

Link to comment
Share on other sites

It's a kind of magic I didn't master :) ... and probably will never do ;) ... one question though, I think we're mainly after the Hyperthreading bit (at least what I understood :) ), and I read it's the 28 bit in EDX, so shouldn't this line

ConsoleWrite("Hyper-Threading Technology: " & BitAND(BitShift(DllStructGetData($tBuffer, 1, 2), 28), 1) & @CRLF) ; bit 28

be more like this?

ConsoleWrite("Hyper-Threading Technology: " & BitAND(BitShift(DllStructGetData($tBuffer, 1, 4), 28), 1) & @CRLF) ; bit 28
The first returned 1 for me, the second 0, and as far as I know this computer doesn't have HT enabled... Great Work!

BitShift(DllStructGetData($tBuffer, 1, 2), 28) should be right because I saved EDX to ($pBuffer + 4) with:

"8915" & SwapEndian($pBuffer + 4) & _                    ; mov dword[$pBuffer + 4], edx
and that is second dword in that array.

♡♡♡

.

eMyvnE

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