Jump to content

Recommended Posts

Posted (edited)

_WinAPI_GetSystemInfo

Posted Image

I needed to get the # of Processors for another project I have, so I was looking into MSDN to find the 'right' way to do it. I've actually stumbled upon a few ways, two are easy - the Environment variable %NUMBER_OF_PROCESSORS%, and also the Registry keys under "HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\" ('tip' has a nice simple function to get that info, _FasterCpuInfo()).

Anyway, this API call seemed like it would be the best source, but this doesn't report on Hyperthreading ('fake') processors that are considered by the Operating System as individual processors.

It turns out, the only 'easy' way to get Hyperthreading info is using the CPUID instruction, or to decipher the array returned by the 'GetLogicalProcessorInformation' API call - which only works with newer OS's. I have since written a function that was a port of Intel source code (mixed with Assembly) that actually worked on the processors we were able to test it on - but it's probably of limited use to most AutoIT programmers, so I'm not including it (for now)

*edit: Fixed a structure descriptor that now allows this function to work correctly in x64 code.

*edit 8/14/09: Fixed it to work correctly in 32-bit mode on an x64 O/S. (needs to call a different API function)

Get the code at my site

Ascend4nt's AutoIT Code License agreement:

While I provide this source code freely, if you do use the code in your projects, all I ask is that:

  • If you provide source, keep the header as I have put it, OR, if you expand it, then at least acknowledge me as the original author, and any other authors I credit
  • If the program is released, acknowledge me in your credits (it doesn't have to state which functions came from me, though again if the source is provided - see #1)
  • The source on it's own (as opposed to part of a project) can not be posted unless a link to the page(s) where the code were retrieved from is provided and a message stating that the latest updates will be available on the page(s) linked to.
  • Pieces of the code can however be discussed on the threads where Ascend4nt has posted the code without worrying about further linking.
Edited by Ascend4nt
  • 3 months later...
  • Replies 82
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted (edited)

Ascend4nt, a really nice script, thanks a lot for this one ;) ! Saw it already some weeks ago, but remembered it when I stumbled across something else...

I'm not quiet sure about this :) , but I think the return value 'lpSystemAffinityMask' of the GetProcessAffinityMask() function (as a bit vector) should match the number of logical processors... well, according to the docs at least for systems with a total of less than 64 processors :) ...

('active logical processors...a process affinity mask is a bit vector in which each bit represents the processors that a process is allowed to run on')

#include <WinAPI.au3>
; GetProcessAffinityMask()
; http://msdn.microsoft.com/en-us/library/ms683213(VS.85).aspx
Global Const $PROCESS_ALL_ACCESS = 0x1F0FFF
$hProc = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, @AutoItPID)
$aRet = _WinAPI_GetProcessAffinityMask($hProc)
MsgBox(0, "", "Success = " & $aRet[0] & @LF & _
              "lpProcessAffinityMask = " & $aRet[1] & @LF & _
              "lpSystemAffinityMask = " & $aRet[2] & @LF & @LF & _
              "# of logical processors = " & Sqrt($aRet[2]+1))
Edited by KaFu
Posted

Kafu, just tried your script - and it returned 4 logical processors. (I have 4 cores, no hyperthreading, so.. ernnhh!! fail!) Sorry! hehe

But you inspired me to try out the 'GetLogicalProcessorInformation' API function (available for O/S's with XP SP3, XP x64, or Server 2003 and above)

What I got, after figuring out the structures and creating a loop to go through them, was the below confusing mess. I can probably ignore the 'Cache' structure info, but how I can determine what logical processors exist, I don't know yet. I'd probably have to send the program I wrote to someone who has Hyperthreading or 'Logical cores'...

One of the problems with this Windows API call is that, not only does it have the above O/S requirements, some of the return values have *further* O/S requirements. Argh, frustrating..

Window's GetLogicalProcessorInformation call Results:

Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #1

Processor Mask:00000001, Relationship:RelationProcessorCore
Processor Core Flags:0
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #2

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

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

Processor Mask:00000002, Relationship:RelationProcessorCore
Processor Core Flags:0
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #5

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

Processor Mask:00000002, Relationship:RelationCache
Cache Descriptor fields:
    Level:1, Associativity:8, (Cache) Line Size, in bytes:64, (Cache) Size, in bytes:32768, Cache type:CacheInstruction
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #7

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

Processor Mask:00000004, Relationship:RelationProcessorCore
Processor Core Flags:0
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #9

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

Processor Mask:00000004, Relationship:RelationCache
Cache Descriptor fields:
    Level:1, Associativity:8, (Cache) Line Size, in bytes:64, (Cache) Size, in bytes:32768, Cache type:CacheInstruction
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #11

Processor Mask:0000000F, Relationship:RelationProcessorPackage
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #12

Processor Mask:00000008, Relationship:RelationProcessorCore
Processor Core Flags:0
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #13

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

Processor Mask:00000008, Relationship:RelationCache
Cache Descriptor fields:
    Level:1, Associativity:8, (Cache) Line Size, in bytes:64, (Cache) Size, in bytes:32768, Cache type:CacheInstruction
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #15

Processor Mask:0000000C, Relationship:RelationCache
Cache Descriptor fields:
    Level:2, Associativity:16, (Cache) Line Size, in bytes:64, (Cache) Size, in bytes:4194304, Cache type:CacheUnified
-------------------------------------------------------------
Processor Information for SYSTEM_LOGICAL_PROCESSOR_INFORMATION, structure #16

Processor Mask:0000000F, Relationship:RelationNumaNode
NumaNode Node Number:0
Posted

I have a dual core laptop, no hyperthreading, and msinfo32 says 2 cores, 2 logical processors. So isn't 4 the right answer for your quad core machine?

Posted (edited)

Well what we are looking for is Logical vs. Actual. Basically, we want to find out which are the Logical/Hyperthreading cores and separate those from the Actual cores, so that we have two counts. For me the 'pretend' cores would be 0..

*edit: maybe I misread what Kafu was trying to communicate? The whole 'logical' business gets confusing here. Anyway, wraithdu, if you could run his program and let me know what it gives you as a result? I could also send you a quick program that gives you output (in and edit box) similar to what I posted above.

Edited by ascendant
Posted (edited)

I think in a multi-core non-hyperthreading system the number of physical and logical processors is the same. Check out the utility on this page and see what your results are -

http://www.codeproject.com/KB/system/countingprocessors.aspx

EDIT -

I ran Kafu's program and it returns 2. His script is going to always count logical processors, which should be >= the number of physical processors.

Edited by wraithdu
Posted

Oops, for some reason I thought you had hyperthreading. haha, I'm misreading a bit today.

Anyway, as expected, that utility reports

CPU Counting Utility

Hyper-threading technology not capable

Number of logical processors per physical processor: 1

Number of physical processors: 4

Press Enter To Continue

If that reported something like '2 logical processors per physical processor', THEN we'd be able to see how many hmm.. need a better term... 'non-physical processors' existed. Hopefully you get what I mean.

Anyway, the CPUID instruction is the only universal way to get the correct information, but it requires Assembly language code. GetLogicalProcessorInformation should report the right information too, but at the moment I don't know how to interpret it (plus we have O/S limitations).

Posted

Right, so Kafu's script is correct on your system - 4 physical processors X 1 logical processor for each physical = 4 logical processors.

Posted

Kafu's script, unless proven otherwise, is the same as _WinAPI_GetSystemInfo() and the variants listed within for getting 'logical' processor counts.

But as I've been trying to say, it's not a way to get a physical processor count - unless, like in mine and your cases, it actually matches. But the code doesn't know that, and that's what we're after - something that runs and detects physical processors vs logical processors. (For example, if I had Hyperthreading available on each core, that would be 4 vs. 8)

Posted

Oh, I thought from your first post you had the physical processors part covered and were just looking for a way to get the logical processors.

From what I'm reading in GetSystemInfo(), it returns the physical processor count, not logical processors. My computer at work is a single core with hyperthreading. It should be a good test for this. I can try this out on Monday.

Posted (edited)

For me the 'pretend' cores would be 0

Just woke up :) ... so, maybe you mean something like

'pretended' cores = Sqrt($aRet[2]+1) from _WinAPI_GetProcessAffinityMask() minus aSysInfo[5] from _WinAPI_GetSystemInfo() :) ?

#include <WinAPI.au3>

$aSysInfo = _WinAPI_GetSystemInfo()

; GetProcessAffinityMask()
; http://msdn.microsoft.com/en-us/library/ms683213(VS.85).aspx
Global Const $PROCESS_ALL_ACCESS = 0x1F0FFF
$hProc = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, @AutoItPID)
$aRet = _WinAPI_GetProcessAffinityMask($hProc)


MsgBox(0, "", "Physical processor count: " & @tab & $aSysInfo[5] & @LF & _
              "Logical processor count: " & @tab & Sqrt($aRet[2]+1) & @LF & _
              "Virtual processor count: " & @tab & Sqrt($aRet[2]+1) - $aSysInfo[5])


; ===================================================================================================
; Func _WinAPI_GetSystemInfo($iInformation=-1)
;
; Retrieves an array of system information, or just one item based on parameter
;
; $iInformation = The piece of information you would like to collect, or -1 for an entire array:
;   1 = Processor Architecture [0 = Intel, 6 = Itanium64, 9 = x64 (AMD or Intel), 0xFFFF = Unknown]
;   2 = Page Size (don't know yet?)
;   3 = Minimum Application Address
;   4 = Maximum Application Address
;   5 = Active Processor Mask - Set Bits indicate processor has been 'configured into the system' (MSDN)
;       [Bit 0 = processor # 0, Bit 31 = processor 31
;   6 = Number of Processors [not the same as 'Logical Processors']
;   7 = Processor Type [386 = Intel 386, 486 = "" 486, 586 = Pentium, 2200 = Itanium64, 8664 = AMD x8664 (?)
;   8 = Allocation Granularity ("granularity for the starting address at which virtual memory can be allocated" - MSDN)
;   9 = Processor Level (1 for Itanium64, otherwise for Processor Architecture 0 it represents CPU-vendor-specific info)
;   10 = Processor Revision (no clue - check out http://msdn.microsoft.com/en-us/library/ms...58(VS.85).aspx)
;
; Return:
;   Success: @error=0, and either a 10-element array filled in the order described above #1 at element [0], #10 at [9],
;       or a # associated with $iInformation
;   Failure: -1 return, @error is set:
;       @error = 1 = invalid parameter (out of range)
;       @error = 2 = DLL call error
;
; Other WinAPI calls to get Processor Info:
;   GetLogicalProcessorInformation  [unfortunately available only on Win XP w/SP3 and higher]
;   IsProcessorFeaturePresent (get processor features information)
;
; Other ways to obtain Processor Information:
;   %NUMBER_OF_PROCESSORS%  Environment variable: Number of Processors (physical, not logical, again)
;       EnvGet("NUMBER_OF_PROCESSORS")
;
;   "HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\"
;       [one subkey for each physical processor, and inside the 1st key (and some inside subsequent ones is)]:
;           Speed, Features set, Processor Name, Identifier, etc.
;
; Author: Ascend4nt
; ===================================================================================================

Func _WinAPI_GetSystemInfo($iInformation=-1)
    If $iInformation<>-1 And ($iInformation<1 Or $iInformation>10) Then Return SetError(1,0,-1)
    Local $aRet,$stSystemInfo=DllStructCreate("ushort;short;dword;ptr;ptr;dword;dword;dword;dword;short;short")

    $aRet=DllCall("kernel32.dll","none","GetSystemInfo","ptr",DllStructGetPtr($stSystemInfo))

    If @error Or Not IsArray($aRet) Then Return SetError(2,0,-1)

    If $iInformation<>-1 Then
        If $iInformation==1 Then Return DllStructGetData($stSystemInfo,1)
        Return DllStructGetData($stSystemInfo,$iInformation+1)
    EndIf
    Local $aSysInfo[10]
    $aSysInfo[0]=DllStructGetData($stSystemInfo,1)
    For $i=1 To 9
        $aSysInfo[$i]=DllStructGetData($stSystemInfo,$i+2)
    Next
    #cs
    ; Full feature display:

    MsgBox(64,"System Info", _
        "Processor Architecture:"&$aSysInfo[0]&@CRLF& _
        "Page Size:"&$aSysInfo[1]&@CRLF& _
        "Minimum Application Address:"&$aSysInfo[2]&@CRLF& _
        "Maximum Application Address:"&$aSysInfo[3]&@CRLF& _
        "Active Processor Mask:"&Hex($aSysInfo[4])&@CRLF& _
        "Number of Processors:"&$aSysInfo[5]&@CRLF& _
        "Processor Type:"&$aSysInfo[6]&@CRLF& _
        "Allocation Granularity:"&$aSysInfo[7]&@CRLF& _
        "Processor Level:"&Hex($aSysInfo[8])&@CRLF& _
        "Processor Revision:"&Hex($aSysInfo[9]))

    #ce
    Return $aSysInfo
EndFunc

Edit: Returns 4,4,0 to me on homebox... Quad core without HT, and 2,2,0 on Notebook, Dual Core without HT, so that should be okay.

Edited by KaFu
Posted

Not a bad tool, thanks ascendant.

Post your code because code says more then your words can. SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y. Use Opt("MustDeclareVars", 1)[topic="84960"]Brett F's Learning To Script with AutoIt V3[/topic][topic="21048"]Valuater's AutoIt 1-2-3, Class... is now in Session[/topic]Contribution: [topic="87994"]Get SVN Rev Number[/topic], [topic="93527"]Control Handle under mouse[/topic], [topic="91966"]A Presentation using AutoIt[/topic], [topic="112756"]Log ConsoleWrite output in Scite[/topic]

Posted

Just woke up :) ... so, maybe you mean something like

'pretended' cores = Sqrt($aRet[2]+1) from _WinAPI_GetProcessAffinityMask() minus aSysInfo[5] from _WinAPI_GetSystemInfo() ;) ?

Edit: Returns 4,4,0 to me on homebox... Quad core without HT, and 2,2,0 on Notebook, Dual Core without HT, so that should be okay.

KaFu, the whole Sqrt thing confuses me.. not even sure what that's about? I thought the Mask was a bit set for each processor? *shrug* :)
Posted (edited)

KaFu, the whole Sqrt thing confuses me.. not even sure what that's about? I thought the Mask was a bit set for each processor? *shrug* :)

Yep, 1 processor = 1, 2 processors = 1+2, 3 processors = 1+2+4, 4 processors = 1+2+4+8. And as this mask returns processor count, each bit to the last has to be one (at least I assume :) ).

E.g. for 4 processors the bitmask is 1111 => 4^2-1 = 15, thus the revision is 4 = Sqrt(15+1)... and yes, I had to think hard about the formulas too ;) , had my last mathematics course just too long ago.

Edited by KaFu
Posted (edited)

You're formula's not quite there:

binary 1: Sqrt(1+1) = 1.414

binary 11111: Sqrt(31 + 1) = 5.656

binary 1111111: Sqrt(127 + 1) = 11.313

I'm still trying to come up with something better. Need a formula to determine how many bits it takes to store a number.

Edited by wraithdu
Posted (edited)

Got it. We need to solve for x in: 2^x = $aRet[2] + 1, where $aRet[2] + 1 is the next bit in the bit vector, since for example the 4th bit has exponent 3 (2^3 = 8). So for a 4 bit vector, the next bit is 16 = 2^4 which is our 4 processors.

processors = Log($aRet[2] + 1) / Log(2)

Edited by wraithdu
Posted

processors = Log($aRet[2] + 1) / Log(2)

Nice ;) , you're right... said my last math course was too long ago :) , just tested for 2 and 4 :)

$i = 1
ConsoleWrite("Sqrt " & Sqrt($i+1) & @CRLF)
ConsoleWrite("Log " & Log($i + 1) / Log(2) & @crlf)
$i = 3
ConsoleWrite("Sqrt " & Sqrt($i+1) & @CRLF)
ConsoleWrite("Log " & Log($i + 1) / Log(2) & @crlf)
$i = 7
ConsoleWrite("Sqrt " & Sqrt($i+1) & @CRLF)
ConsoleWrite("Log " & Log($i + 1) / Log(2) & @crlf)
$i = 15
ConsoleWrite("Sqrt " & Sqrt($i+1) & @CRLF)
ConsoleWrite("Log " & Log($i + 1) / Log(2) & @crlf)
$i = 31
ConsoleWrite("Sqrt " & Sqrt($i+1) & @CRLF)
ConsoleWrite("Log " & Log($i + 1) / Log(2) & @crlf)

And heres an update of the functions...

#include <WinAPI.au3>

$aSysInfo = _WinAPI_GetSystemInfo()

; GetProcessAffinityMask()
; http://msdn.microsoft.com/en-us/library/ms683213(VS.85).aspx
Global Const $PROCESS_ALL_ACCESS = 0x1F0FFF
$hProc = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, @AutoItPID)
$aRet = _WinAPI_GetProcessAffinityMask($hProc)


MsgBox(0, "", "Physical processor count: " & @tab & $aSysInfo[5] & @LF & _
              "Logical processor count: " & @tab & (Log($aRet[2] + 1) / Log(2)) & @LF & _
              "Virtual processor count: " & @tab & (Log($aRet[2] + 1) / Log(2)) - $aSysInfo[5])


; ===================================================================================================
; Func _WinAPI_GetSystemInfo($iInformation=-1)
;
; Retrieves an array of system information, or just one item based on parameter
;
; $iInformation = The piece of information you would like to collect, or -1 for an entire array:
;   1 = Processor Architecture [0 = Intel, 6 = Itanium64, 9 = x64 (AMD or Intel), 0xFFFF = Unknown]
;   2 = Page Size (don't know yet?)
;   3 = Minimum Application Address
;   4 = Maximum Application Address
;   5 = Active Processor Mask - Set Bits indicate processor has been 'configured into the system' (MSDN)
;       [Bit 0 = processor # 0, Bit 31 = processor 31
;   6 = Number of Processors [not the same as 'Logical Processors']
;   7 = Processor Type [386 = Intel 386, 486 = "" 486, 586 = Pentium, 2200 = Itanium64, 8664 = AMD x8664 (?)
;   8 = Allocation Granularity ("granularity for the starting address at which virtual memory can be allocated" - MSDN)
;   9 = Processor Level (1 for Itanium64, otherwise for Processor Architecture 0 it represents CPU-vendor-specific info)
;   10 = Processor Revision (no clue - check out http://msdn.microsoft.com/en-us/library/ms...58(VS.85).aspx)
;
; Return:
;   Success: @error=0, and either a 10-element array filled in the order described above #1 at element [0], #10 at [9],
;       or a # associated with $iInformation
;   Failure: -1 return, @error is set:
;       @error = 1 = invalid parameter (out of range)
;       @error = 2 = DLL call error
;
; Other WinAPI calls to get Processor Info:
;   GetLogicalProcessorInformation  [unfortunately available only on Win XP w/SP3 and higher]
;   IsProcessorFeaturePresent (get processor features information)
;
; Other ways to obtain Processor Information:
;   %NUMBER_OF_PROCESSORS%  Environment variable: Number of Processors (physical, not logical, again)
;       EnvGet("NUMBER_OF_PROCESSORS")
;
;   "HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\"
;       [one subkey for each physical processor, and inside the 1st key (and some inside subsequent ones is)]:
;           Speed, Features set, Processor Name, Identifier, etc.
;
; Author: Ascend4nt
; ===================================================================================================

Func _WinAPI_GetSystemInfo($iInformation=-1)
    If $iInformation<>-1 And ($iInformation<1 Or $iInformation>10) Then Return SetError(1,0,-1)
    Local $aRet,$stSystemInfo=DllStructCreate("ushort;short;dword;ptr;ptr;dword;dword;dword;dword;short;short")

    $aRet=DllCall("kernel32.dll","none","GetSystemInfo","ptr",DllStructGetPtr($stSystemInfo))

    If @error Or Not IsArray($aRet) Then Return SetError(2,0,-1)

    If $iInformation<>-1 Then
        If $iInformation==1 Then Return DllStructGetData($stSystemInfo,1)
        Return DllStructGetData($stSystemInfo,$iInformation+1)
    EndIf
    Local $aSysInfo[10]
    $aSysInfo[0]=DllStructGetData($stSystemInfo,1)
    For $i=1 To 9
        $aSysInfo[$i]=DllStructGetData($stSystemInfo,$i+2)
    Next
    #cs
    ; Full feature display:

    MsgBox(64,"System Info", _
        "Processor Architecture:"&$aSysInfo[0]&@CRLF& _
        "Page Size:"&$aSysInfo[1]&@CRLF& _
        "Minimum Application Address:"&$aSysInfo[2]&@CRLF& _
        "Maximum Application Address:"&$aSysInfo[3]&@CRLF& _
        "Active Processor Mask:"&Hex($aSysInfo[4])&@CRLF& _
        "Number of Processors:"&$aSysInfo[5]&@CRLF& _
        "Processor Type:"&$aSysInfo[6]&@CRLF& _
        "Allocation Granularity:"&$aSysInfo[7]&@CRLF& _
        "Processor Level:"&Hex($aSysInfo[8])&@CRLF& _
        "Processor Revision:"&Hex($aSysInfo[9]))

    #ce
    Return $aSysInfo
EndFunc
Posted

Here's another interesting bit to get the number of active processors in the affinity mask. This would work up to 32 processors, since the AutoIt bit functions only work on 32-bit numbers.

$mask = 127
$nProcs = 0
For $i = 1 To 32
    If BitAND($mask, 2^($i-1)) Then $nProcs += 1
Next
ConsoleWrite("# of active processors:  " & $nProcs & @CRLF)
Posted (edited)

Or, assuming there are not gaps in the $aMask[2] - System affinity mask (as opposed to the $aMask[1] - Process affinity mask, where gaps indicate that a process should not run on that core) :) ...

$mask = 127
$nProcs = 0
For $i = 1 To 32
    If BitAND($mask, 2^($i-1)) Then $nProcs = $i
Next
ConsoleWrite("# of logical processors:  " & $nProcs & @CRLF)
Edited by KaFu
Posted

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

Local $iTotalCPUs=0
   ; Remove topbit, otherwise the function will enter an endless loop
    Local $iUnsignedNumber=BitAND($iProcessorNumber,0x7FFFFFFF)
   
   ; Cycle through each bit, shifting to the right until 0
    Do
        $iTotalCPUs+=BitAND($iUnsignedNumber,1)
        $iUnsignedNumber=BitShift($iUnsignedNumber,1)
    Until Not $iUnsignedNumber

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

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
×
×
  • Create New...