CPU Features.GetCount return CPU 核心数不正确
CPU Features.GetCount return incorrect number for CPU Cores
我正在使用 CPU 功能插件来获取 CPU 核心,这是代码:
${CPUFeatures.GetCount} $CPUCore
显然,有一台计算机有 12 CPU 个内核,而 $CPUCore 显示只有 1 个内核。我想也许 $CPUCore 可能只有 return 第一个数字,但我怎么能确定呢?
或者,还有其他方法可以得到 CPU 核心数字吗?
我不知道为什么插件会失败,但你可以问 Windows 这样的问题:
!include LogicLib.nsh
!ifndef ERROR_INSUFFICIENT_BUFFER
!define ERROR_INSUFFICIENT_BUFFER 122
!endif
!define RelationProcessorCore 0
!if "${NSIS_PTR_SIZE}" <= 4
Function GetProcessorPhysCoreCount
System::Store S
StrCpy 0 ; 0 if we fail
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},i,*i0r2)i.r0?e'
Pop
${If} = ${ERROR_INSUFFICIENT_BUFFER}
${AndIf} <> 0
System::Alloc
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},isr1,*ir2r2)i.r0'
Push
${If} [=10=] <> 0
loop_7:
IntOp + 1
System::Call *(i,i.r3)
IntOp +
IntOp -
IntCmp 0 "" loop_7 loop_7
${EndIf}
Pop
System::Free
${Else}
System::Call 'kernel32::GetLogicalProcessorInformation(i,*i0r2)i.r0?e'
Pop
${If} = ${ERROR_INSUFFICIENT_BUFFER}
System::Alloc
System::Call 'kernel32::GetLogicalProcessorInformation(isr1,*ir2r2)i.r0'
Push
${If} [=10=] <> 0
loop_v:
System::Call *(i,i.r3)
${If} = ${RelationProcessorCore}
IntOp + 1
${EndIf}
IntOp + 24
IntOp - 24
IntCmp 0 "" loop_v loop_v
${EndIf}
Pop
System::Free
${EndIf}
${EndIf}
Push
System::Store L
FunctionEnd
Function CountSetBits32
Exch [=10=]
Push
Push
Push
StrCpy 0
StrCpy 0
loop:
IntOp 1 <<
IntOp & [=10=]
${IfThen} <> 0 ${|} IntOp + 1 ${|}
IntOp + 1
StrCmp 32 "" loop
StrCpy [=10=]
Pop
Pop
Pop
Exch [=10=]
FunctionEnd
Function GetProcessorLogicalCoreCount
System::Store S
StrCpy 0 ; 0 if we fail
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},i,*i0r2)i.r0?e'
Pop
${If} = ${ERROR_INSUFFICIENT_BUFFER}
${AndIf} <> 0
System::Alloc
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},isr1,*ir2r2)i.r0'
Push
${If} [=10=] <> 0
loop_7:
System::Call *(i,i.r3,&i22,&i2,i.r5)
Push
Call CountSetBits32
Pop
IntOp +
IntOp +
IntOp -
IntCmp 0 "" loop_7 loop_7
${EndIf}
Pop
System::Free
${Else}
System::Call 'kernel32::GetLogicalProcessorInformation(i,*i0r2)i.r0?e'
Pop
${If} = ${ERROR_INSUFFICIENT_BUFFER}
System::Alloc
System::Call 'kernel32::GetLogicalProcessorInformation(isr1,*ir2r2)i.r0'
Push
${If} [=10=] <> 0
loop_v:
System::Call *(i,i.r3)
${If} = ${RelationProcessorCore}
System::Call *(i.r3)
Push
Call CountSetBits32
Pop
IntOp +
${EndIf}
IntOp + 24
IntOp - 24
IntCmp 0 "" loop_v loop_v
${EndIf}
Pop
System::Free
${EndIf}
${EndIf}
Push
System::Store L
FunctionEnd
!endif
Section
Call GetProcessorPhysCoreCount
Pop [=10=]
Call GetProcessorLogicalCoreCount
Pop
DetailPrint PhysCores=[=10=],LogicalCores=
SectionEnd
您仍应使用 ${CPUFeatures.GetCount} 作为后备方案,因为 GetLogicalProcessorInformation[Ex] 并不存在于所有版本的 Windows...
我尝试使用此 forum 中的代码并对其进行了一些修改,因此我只获得了处理器核心编号:
!include "LogicLib.nsh"
!define ERROR_INSUFFICIENT_BUFFER 122
; Size of SYSTEM_LOGICAL_PROCESSOR_INFORMATION on 32-bit systems
!define SYS_LOG_PROC_INFO_SIZE 24
; Offset of Relationship in the SYSTEM_LOGICAL_PROCESSOR_INFORMATION structure
!define RELATIONSHIP_OFFSET 4
; Enum value of Relationship identifying Processor Core
!define RELATIONPROCESSORCORE 0
; Count the number of bits set in given value
; Parameters: value
; Returns: number of bits set in given value
Function countbits
Exch [=10=]
Push
Push
; Set initial value for number of bits set in [=10=]
StrCpy 0
${While} [=10=] > 0
; Clear least significant bit set
IntOp [=10=] - 1
IntOp [=10=] [=10=] &
; Increment number of bits set
IntOp + 1
${EndWhile}
; Return number of bits set
StrCpy [=10=]
Pop
Pop
Exch [=10=]
FunctionEnd
; Evaluate processor information
; Paramaters: buffer, length
; Returns: number of cores
Function evalcpuinfo
Exch [=10=] ; length
Exch
Exch ; buffer
Push
Push
Push
Push ; Processor Cores
Push ; Logical Processors
; Set buffer offset at the end of the buffer
StrCpy [=10=]
; Initialize number of Processor Cores and Logical Processors
StrCpy 0
StrCpy 0
; Iterate through buffer starting from end
${While} >= ${SYS_LOG_PROC_INFO_SIZE}
; Calculate start address of an element
IntOp - ${SYS_LOG_PROC_INFO_SIZE}
IntOp +
; Get ProcessorMask value from element
System::Call "*(i.r4)"
Push
IntOp + ${RELATIONSHIP_OFFSET}
; Get Relationship value from element
System::Call "*(i.r4)"
${If} == ${RELATIONPROCESSORCORE}
; Increment Processor cores
IntOp + 1
; Determine number of Logical Processor by counting the bits
; set in the value of ProcessorMask
Call countbits
Pop
; Sum up Logical Processors
IntOp +
${Else}
Pop
${EndIf}
${EndWhile}
; Set processor information as return value
StrCpy [=10=]
Pop
Pop
Pop
Pop
Pop
Pop
Exch [=10=]
FunctionEnd
; Get processor information
; Returns: number of Processor Cores and Logical Processors
Function getcpuinfo
Push [=10=]
Push
Push
Push
Push
; GetLogicalProcessorInformation is only available on
; Windows XP SP3 or its successors.
; Initialize buffer and its length
StrCpy 0
StrCpy 0
; Determine required length of buffer
System::Call "kernel32::GetLogicalProcessorInformation(ir1, *ir2r2) i.r3 ? e"
Pop
${If} == 0
${If} == ${ERROR_INSUFFICIENT_BUFFER}
; Allocate buffer
System::Alloc
Pop
${If} != 0
; Get processor information
System::Call "kernel32::GetLogicalProcessorInformation(ir1, *ir2r2) i.r3 ? e"
Pop
${If} != 1
StrCpy [=10=] "Error: "
${Else}
Push ; buffer
Push ; length
Call evalcpuinfo
Pop [=10=]
${EndIf}
; Deallocate buffer
System::Free
${Else}
StrCpy [=10=] "Error: memory allocation failed!"
${EndIf}
${Else}
StrCpy [=10=] "Error: "
${EndIf}
${Else}
StrCpy [=10=] "GetLogicalProcessorInformation is not available on your system!"
${EndIf}
Pop
Pop
Pop
Pop
Exch [=10=]
FunctionEnd
我觉得代码和Anders的代码很相似。我已经在三台不同的 PC 上进行了尝试,并获得了正确的处理器核心编号。
我正在使用 CPU 功能插件来获取 CPU 核心,这是代码:
${CPUFeatures.GetCount} $CPUCore
显然,有一台计算机有 12 CPU 个内核,而 $CPUCore 显示只有 1 个内核。我想也许 $CPUCore 可能只有 return 第一个数字,但我怎么能确定呢?
或者,还有其他方法可以得到 CPU 核心数字吗?
我不知道为什么插件会失败,但你可以问 Windows 这样的问题:
!include LogicLib.nsh
!ifndef ERROR_INSUFFICIENT_BUFFER
!define ERROR_INSUFFICIENT_BUFFER 122
!endif
!define RelationProcessorCore 0
!if "${NSIS_PTR_SIZE}" <= 4
Function GetProcessorPhysCoreCount
System::Store S
StrCpy 0 ; 0 if we fail
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},i,*i0r2)i.r0?e'
Pop
${If} = ${ERROR_INSUFFICIENT_BUFFER}
${AndIf} <> 0
System::Alloc
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},isr1,*ir2r2)i.r0'
Push
${If} [=10=] <> 0
loop_7:
IntOp + 1
System::Call *(i,i.r3)
IntOp +
IntOp -
IntCmp 0 "" loop_7 loop_7
${EndIf}
Pop
System::Free
${Else}
System::Call 'kernel32::GetLogicalProcessorInformation(i,*i0r2)i.r0?e'
Pop
${If} = ${ERROR_INSUFFICIENT_BUFFER}
System::Alloc
System::Call 'kernel32::GetLogicalProcessorInformation(isr1,*ir2r2)i.r0'
Push
${If} [=10=] <> 0
loop_v:
System::Call *(i,i.r3)
${If} = ${RelationProcessorCore}
IntOp + 1
${EndIf}
IntOp + 24
IntOp - 24
IntCmp 0 "" loop_v loop_v
${EndIf}
Pop
System::Free
${EndIf}
${EndIf}
Push
System::Store L
FunctionEnd
Function CountSetBits32
Exch [=10=]
Push
Push
Push
StrCpy 0
StrCpy 0
loop:
IntOp 1 <<
IntOp & [=10=]
${IfThen} <> 0 ${|} IntOp + 1 ${|}
IntOp + 1
StrCmp 32 "" loop
StrCpy [=10=]
Pop
Pop
Pop
Exch [=10=]
FunctionEnd
Function GetProcessorLogicalCoreCount
System::Store S
StrCpy 0 ; 0 if we fail
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},i,*i0r2)i.r0?e'
Pop
${If} = ${ERROR_INSUFFICIENT_BUFFER}
${AndIf} <> 0
System::Alloc
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},isr1,*ir2r2)i.r0'
Push
${If} [=10=] <> 0
loop_7:
System::Call *(i,i.r3,&i22,&i2,i.r5)
Push
Call CountSetBits32
Pop
IntOp +
IntOp +
IntOp -
IntCmp 0 "" loop_7 loop_7
${EndIf}
Pop
System::Free
${Else}
System::Call 'kernel32::GetLogicalProcessorInformation(i,*i0r2)i.r0?e'
Pop
${If} = ${ERROR_INSUFFICIENT_BUFFER}
System::Alloc
System::Call 'kernel32::GetLogicalProcessorInformation(isr1,*ir2r2)i.r0'
Push
${If} [=10=] <> 0
loop_v:
System::Call *(i,i.r3)
${If} = ${RelationProcessorCore}
System::Call *(i.r3)
Push
Call CountSetBits32
Pop
IntOp +
${EndIf}
IntOp + 24
IntOp - 24
IntCmp 0 "" loop_v loop_v
${EndIf}
Pop
System::Free
${EndIf}
${EndIf}
Push
System::Store L
FunctionEnd
!endif
Section
Call GetProcessorPhysCoreCount
Pop [=10=]
Call GetProcessorLogicalCoreCount
Pop
DetailPrint PhysCores=[=10=],LogicalCores=
SectionEnd
您仍应使用 ${CPUFeatures.GetCount} 作为后备方案,因为 GetLogicalProcessorInformation[Ex] 并不存在于所有版本的 Windows...
我尝试使用此 forum 中的代码并对其进行了一些修改,因此我只获得了处理器核心编号:
!include "LogicLib.nsh"
!define ERROR_INSUFFICIENT_BUFFER 122
; Size of SYSTEM_LOGICAL_PROCESSOR_INFORMATION on 32-bit systems
!define SYS_LOG_PROC_INFO_SIZE 24
; Offset of Relationship in the SYSTEM_LOGICAL_PROCESSOR_INFORMATION structure
!define RELATIONSHIP_OFFSET 4
; Enum value of Relationship identifying Processor Core
!define RELATIONPROCESSORCORE 0
; Count the number of bits set in given value
; Parameters: value
; Returns: number of bits set in given value
Function countbits
Exch [=10=]
Push
Push
; Set initial value for number of bits set in [=10=]
StrCpy 0
${While} [=10=] > 0
; Clear least significant bit set
IntOp [=10=] - 1
IntOp [=10=] [=10=] &
; Increment number of bits set
IntOp + 1
${EndWhile}
; Return number of bits set
StrCpy [=10=]
Pop
Pop
Exch [=10=]
FunctionEnd
; Evaluate processor information
; Paramaters: buffer, length
; Returns: number of cores
Function evalcpuinfo
Exch [=10=] ; length
Exch
Exch ; buffer
Push
Push
Push
Push ; Processor Cores
Push ; Logical Processors
; Set buffer offset at the end of the buffer
StrCpy [=10=]
; Initialize number of Processor Cores and Logical Processors
StrCpy 0
StrCpy 0
; Iterate through buffer starting from end
${While} >= ${SYS_LOG_PROC_INFO_SIZE}
; Calculate start address of an element
IntOp - ${SYS_LOG_PROC_INFO_SIZE}
IntOp +
; Get ProcessorMask value from element
System::Call "*(i.r4)"
Push
IntOp + ${RELATIONSHIP_OFFSET}
; Get Relationship value from element
System::Call "*(i.r4)"
${If} == ${RELATIONPROCESSORCORE}
; Increment Processor cores
IntOp + 1
; Determine number of Logical Processor by counting the bits
; set in the value of ProcessorMask
Call countbits
Pop
; Sum up Logical Processors
IntOp +
${Else}
Pop
${EndIf}
${EndWhile}
; Set processor information as return value
StrCpy [=10=]
Pop
Pop
Pop
Pop
Pop
Pop
Exch [=10=]
FunctionEnd
; Get processor information
; Returns: number of Processor Cores and Logical Processors
Function getcpuinfo
Push [=10=]
Push
Push
Push
Push
; GetLogicalProcessorInformation is only available on
; Windows XP SP3 or its successors.
; Initialize buffer and its length
StrCpy 0
StrCpy 0
; Determine required length of buffer
System::Call "kernel32::GetLogicalProcessorInformation(ir1, *ir2r2) i.r3 ? e"
Pop
${If} == 0
${If} == ${ERROR_INSUFFICIENT_BUFFER}
; Allocate buffer
System::Alloc
Pop
${If} != 0
; Get processor information
System::Call "kernel32::GetLogicalProcessorInformation(ir1, *ir2r2) i.r3 ? e"
Pop
${If} != 1
StrCpy [=10=] "Error: "
${Else}
Push ; buffer
Push ; length
Call evalcpuinfo
Pop [=10=]
${EndIf}
; Deallocate buffer
System::Free
${Else}
StrCpy [=10=] "Error: memory allocation failed!"
${EndIf}
${Else}
StrCpy [=10=] "Error: "
${EndIf}
${Else}
StrCpy [=10=] "GetLogicalProcessorInformation is not available on your system!"
${EndIf}
Pop
Pop
Pop
Pop
Exch [=10=]
FunctionEnd
我觉得代码和Anders的代码很相似。我已经在三台不同的 PC 上进行了尝试,并获得了正确的处理器核心编号。