Sign in to follow this  
Followers 0
Ascend4nt

_WinAPI_GetSystemInfo

83 posts in this topic

#1 ·  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

Share this post


Link to post
Share on other sites



#2 ·  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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

#5 ·  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

Share this post


Link to post
Share on other sites

#6 ·  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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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)

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

#11 ·  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

Share this post


Link to post
Share on other sites

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]

Share this post


Link to post
Share on other sites

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* :)

Share this post


Link to post
Share on other sites

#14 ·  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

Share this post


Link to post
Share on other sites

#15 ·  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

Share this post


Link to post
Share on other sites

#16 ·  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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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)

Share this post


Link to post
Share on other sites

#19 ·  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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
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
Sign in to follow this  
Followers 0

  • Similar Content

    • UEZ
      By UEZ
      is a small tool in widget style to show the clock, current cpu usage, cpu speed,
      memory usage and network activity (tcp, ip and udp). Additionally you can use it as an alarm clock (to stop
      alarm clock tone press the left LED (mail) or wait 60 seconds).

      The current cpu usage code is beta and might be not working for some CPU models! Autoit SysInfo Clock should
      work with all operating systems beginning from Windows XP.

      Br,
      UEZ


      This project is discontinued!
    • UEZ
      By UEZ
      AutoIt SysInfo Clock is a small tool in widget style to show the clock, current CPU usage, CPU speed, memory usage and network activity (tcp, ip and udp). Additionally you can use it as an alarm clock. To stop alarm clock tone press the left LED (mail) or wait 60 seconds.
       
      The current CPU usage code is beta and might be not working for some CPUs!

      Main window:

      Move mouse to area below seconds and press rmb to select different color scheme.

      Alarm Clock window:


      Tray menu:



       
      Credits: see scroller (select About).
       
      Special thanks to trancexx for helping me to read out current CPU speed using the WinAPI stuff, AndyG for troubleshooting performance counter issue, czardas for composing "Für Elise" and Ascend4nt for the support!  
       
       
      Download source code + compiled version: Click Me (previous downloads: 1386)
      (Please don't use any download manager!)
       
      Compiled version only: MediaFire.com or 4Shared.com
       

      Coded on Win7 x64 using Aero  / Win8.1 x64 and AutoIt v3.3.12.0.
       
       
      Br,
      UEZ
       
       
      This project is discontinued!
       
       
      Change log:
      v0.9.5.0 build 2013-06-14: initial release
      v0.9.6.0 build 2013-06-15: added _WinAPI_CreateRoundRectRgn() to fix transparency issue on non Aero desktops, small internal modifications and added check for whether performance counters are enabled
      v0.9.6.5 build 2013-06-15: fixed a bug when "Reset Windows Position" was selected twice and color of scroller will fit to clock color schema
      v0.9.8.0 build 2013-06-20: added little music to About part -> many thanks to czardas for mus++ and arranging "Für Elise", added date to clock, replaced CPU usage code -> thanks Ascend4nt
      v0.9.9.0 build 2013-06-21: added 2 more color schemas (mint and purple), added network traffic LED, compiled exe now included in archive
      v0.9.9.0 build 2013-06-22: forgot to increase a variable in ini section
      v0.9.9.0 build 2013-06-24: found also missing modification in context menue after adding two more color schemas
      v0.9.9.0 build 2013-06-26: Ops, forgot to change also radio item proper check in clock color schema sub menu
      v0.9.9.1 build 2013-06-27: added option to select whether SysInfo Clock should start at windows startup
      v0.9.9.2 build 2013-07-01: added yellow-red mark to the small info indicators and additional info when hovering about the small indicators, small internal changes
      v0.9.9.5 build 2013-07-05: added features: singleton, update check, visit web site, bring GUI to front and fixed some smaller bugs + some internal changes
      v0.9.9.6 build 2013-07-11: added alarm clock feature
      v0.9.9.7 build 2014-06-23: adapted code to run on AutoIt version 3.3.12.0
      v0.9.9.7 build 2014-08-27: some internal "cosmetic" changes -> this project is discontinued!
    • Blinky
      By Blinky
      Hi everyone,
      This is my special pet project.
      It is an example of how u can use autoit to control external devices.
      this script is made to comunicate with the MAX335 chip  using the SPI protocol via the LPT(printer) port
      the beauty of the MAX335 chip is that the Clock, Data_In and the Chip_Select pins can be directly connected to the LPT port without any external components, and the 12V and 5V directly from an ATX PC power suply.
      aditionaly i made a custom GUI with CommandFusion instaled on an Android Tablet that sends TCP commands to an Autoit TCP server that controls three dasy chained MAX335 chips that totals 24 independent NO switches
      this script works perfectly for me
      i just finished this project and i think i will make an UDF including more SPI devices
      $DLLFileAndPath = @ScriptDir & "/inpout32.dll" Global $335_device_number=3 ;number of daisy chained chips Global $335_clock_bit=0 ;bit number for LPT pin 1 in the control Register of the LPT port(where i connected the CLK pin on te MAX335) Global $335_cs_bit=4;bit number for LPT pin 6 in the data Register of the LPT port(where i connected the CS pin on te MAX335) Global $335_data_in_bit=7;bit number for LPT pin 9 in the data Register of the LPT port(where i connected the DI pin on te MAX335) Global $clock_delay=1;this limits the clock speed but it works fine with 0 ;the ini file will be created and will keep the MAX335 pins statuses For $i=0 To $335_device_number*8-1 Step 1 IniWrite("355_buffer.ini","present_data",$i,"0") Next set_max335_output(2,3,1) ; this will activate switch 2 on device 3 on the daisy chain Func set_max335_output($output_no,$device_no,$status) $bit_no=($device_no-1)*8+$output_no-1 ; get the exact bit number of the switch IniWrite("355_buffer.ini","present_data",$bit_no,$status); whrite it to the buffer ;this part is where the SPI protocol begins set_control_bit($335_clock_bit,1); drop CLK set_data_bit($335_cs_bit,0) ;activate CS Sleep($clock_delay) For $i=$335_device_number*8-1 To 0 Step -1; start writing from buffer MostSignificantByte first $data=IniRead("355_buffer.ini","present_data",$i,"0") set_data_bit($335_data_in_bit,$data) ; set data bit value set_control_bit($335_clock_bit,0) ;raise CLK Sleep($clock_delay) set_control_bit($335_clock_bit,1); drop CLK Sleep($clock_delay) Next set_data_bit($335_cs_bit,1);deactivate CS EndFunc Func set_data_bit($bit,$stat=-1) ; it will write the value of the bit in the data reg of the LPT port $y= DllCall($DLLFileAndPath, "int", "Inp32", "int", "0x378") $bits=dec_to_bin($y[0]) If $stat = -1 Then If $bits[$bit]=0 Then $bits[$bit]=1 Else $bits[$bit]=0 EndIf $bcd=bin_to_dec($bits) DllCall( $DLLFileAndPath, "int", "Out32", "int", "0x378", "int", $bcd) Return 1 Else If $bits[$bit]<>$stat Then $bits[$bit]=$stat $bcd=bin_to_dec($bits) DllCall( $DLLFileAndPath, "int", "Out32", "int", "0x378", "int", $bcd) Return 1 Else Return 2 EndIf EndIf EndFunc Func set_control_bit($bit,$stat=-1); it will write the value of the bit in the control reg of the LPT port $y= DllCall($DLLFileAndPath, "int", "Inp32", "int", "0x37a") $bits=dec_to_bin($y[0]) If $stat = -1 Then If $bits[$bit]=0 Then $bits[$bit]=1 Else $bits[$bit]=0 EndIf $bcd=bin_to_dec($bits) DllCall( $DLLFileAndPath, "int", "Out32", "int", "0x37a", "int", $bcd) Return 1 Else If $bits[$bit]<>$stat Then $bits[$bit]=$stat $bcd=bin_to_dec($bits) DllCall( $DLLFileAndPath, "int", "Out32", "int", "0x37a", "int", $bcd) Return 1 Else Return 2 EndIf EndIf EndFunc Func dec_to_bin($dec) Local $bit_array[8] If $dec > 255 Then SetError(1,1,-1) If $dec < 0 Then SetError(2,1,-1) For $i=7 To 0 Step -1 If $dec >= 2^$i Then $bit_array[$i] = 1 $dec=$dec-2^$i Else $bit_array[$i] = 0 EndIf Next Return $bit_array EndFunc Func bin_to_dec($bit_array) If IsArray($bit_array) Then If UBound($bit_array) = 8 Then $dec=0 For $i=7 To 0 Step -1 $dec = $bit_array[$i]*(2^$i)+$dec Next Else SetError(2,1,-1) EndIf Else SetError(1,1,-1) EndIf Return $dec EndFunc