Nsis CPU Features.GetCount返回不正确的CPU核心数

Nsis CPU Features.GetCount返回不正确的CPU核心数,nsis,cpu-cores,Nsis,Cpu Cores,我正在使用CPU功能插件获取CPU核心,代码如下: ${CPUFeatures.GetCount} $CPUCore 显然,有一台计算机有12个CPU内核,$CPUCore只显示1个内核。我想$CPUCore可能只返回第一个数字,但我怎么能确定呢 或者,有没有其他方法来获取CPU核心号?我不知道插件为什么会失败,但你可以问Windows这样的问题: !include LogicLib.nsh !ifndef ERROR_INSUFFICIENT_BUFFER !define ERROR_INS

我正在使用CPU功能插件获取CPU核心,代码如下:

${CPUFeatures.GetCount} $CPUCore
显然,有一台计算机有12个CPU内核,$CPUCore只显示1个内核。我想$CPUCore可能只返回第一个数字,但我怎么能确定呢


或者,有没有其他方法来获取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 $9 0 ; 0 if we fail
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},i,*i0r2)i.r0?e'
Pop $3
${If} $3 = ${ERROR_INSUFFICIENT_BUFFER}
${AndIf} $2 <> 0
    System::Alloc $2
    System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},isr1,*ir2r2)i.r0'
    Push $1
    ${If} $0 <> 0
    loop_7:
        IntOp $9 $9 + 1
        System::Call *$1(i,i.r3)
        IntOp $1 $1 + $3
        IntOp $2 $2 - $3
        IntCmp $2 0 "" loop_7 loop_7
    ${EndIf}
    Pop $1
    System::Free $1
${Else}
    System::Call 'kernel32::GetLogicalProcessorInformation(i,*i0r2)i.r0?e'
    Pop $3
    ${If} $3 = ${ERROR_INSUFFICIENT_BUFFER}
        System::Alloc $2
        System::Call 'kernel32::GetLogicalProcessorInformation(isr1,*ir2r2)i.r0'
        Push $1
        ${If} $0 <> 0
        loop_v:
            System::Call *$1(i,i.r3)
            ${If} $3 = ${RelationProcessorCore}
                IntOp $9 $9 + 1
            ${EndIf}
            IntOp $1 $1 + 24
            IntOp $2 $2 - 24
            IntCmp $2 0 "" loop_v loop_v
        ${EndIf}
        Pop $1
        System::Free $1
    ${EndIf}
${EndIf}
Push $9
System::Store L
FunctionEnd

Function CountSetBits32
Exch $0
Push $1
Push $2
Push $3
StrCpy $3 0
StrCpy $1 0
loop:
    IntOp $2 1 << $1
    IntOp $2 $2 & $0
    ${IfThen} $2 <> 0 ${|} IntOp $3 $3 + 1 ${|}
    IntOp $1 $1 + 1
    StrCmp $1 32 "" loop
StrCpy $0 $3
Pop $3
Pop $2
Pop $1
Exch $0
FunctionEnd

Function GetProcessorLogicalCoreCount
System::Store S
StrCpy $9 0 ; 0 if we fail
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},i,*i0r2)i.r0?e'
Pop $3
${If} $3 = ${ERROR_INSUFFICIENT_BUFFER}
${AndIf} $2 <> 0
    System::Alloc $2
    System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},isr1,*ir2r2)i.r0'
    Push $1
    ${If} $0 <> 0
    loop_7:
        System::Call *$1(i,i.r3,&i22,&i2,i.r5)
        Push $5
        Call CountSetBits32
        Pop $5
        IntOp $9 $9 + $5
        IntOp $1 $1 + $3
        IntOp $2 $2 - $3
        IntCmp $2 0 "" loop_7 loop_7
    ${EndIf}
    Pop $1
    System::Free $1
${Else}
    System::Call 'kernel32::GetLogicalProcessorInformation(i,*i0r2)i.r0?e'
    Pop $3
    ${If} $3 = ${ERROR_INSUFFICIENT_BUFFER}
        System::Alloc $2
        System::Call 'kernel32::GetLogicalProcessorInformation(isr1,*ir2r2)i.r0'
        Push $1
        ${If} $0 <> 0
        loop_v:
            System::Call *$1(i,i.r3)
            ${If} $3 = ${RelationProcessorCore}
                System::Call *$1(i.r3)
                Push $3
                Call CountSetBits32
                Pop $3
                IntOp $9 $9 + $3
            ${EndIf}
            IntOp $1 $1 + 24
            IntOp $2 $2 - 24
            IntCmp $2 0 "" loop_v loop_v
        ${EndIf}
        Pop $1
        System::Free $1
    ${EndIf}
${EndIf}
Push $9
System::Store L
FunctionEnd
!endif

Section
Call GetProcessorPhysCoreCount
Pop $0
Call GetProcessorLogicalCoreCount
Pop $1
DetailPrint PhysCores=$0,LogicalCores=$1
SectionEnd
!包括LogicLib.nsh
!ifndef错误\u缓冲区不足\u
!定义错误\u不足\u缓冲区122
!恩迪夫
!定义RelationProcessorCore 0

!如果“${NSIS_PTR_SIZE}”我尝试使用此代码,并对其进行了一点修改,以便只获得处理器核心编号:

!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 $0 
   Push $1 
   Push $2 

   ; Set initial value for number of bits set in $0 
   StrCpy $1 0 

   ${While} $0 > 0 
      ; Clear least significant bit set 
      IntOp $2 $0 - 1 
      IntOp $0 $0 & $2 
      ; Increment number of bits set 
      IntOp $1 $1 + 1 
   ${EndWhile} 

   ; Return number of bits set 
   StrCpy $0 $1 

   Pop $2 
   Pop $1 
   Exch $0 
FunctionEnd 

; Evaluate processor information 
; Paramaters: buffer, length 
; Returns: number of cores 
Function evalcpuinfo 
   Exch $0 ; length 
   Exch 
   Exch $1 ; buffer 
   Push $2 
   Push $3 
   Push $4 
   Push $5 ; Processor Cores 
   Push $6 ; Logical Processors 

   ; Set buffer offset at the end of the buffer 
   StrCpy $2 $0 

   ; Initialize number of Processor Cores and Logical Processors 
   StrCpy $5 0 
   StrCpy $6 0 

   ; Iterate through buffer starting from end 
   ${While} $2 >= ${SYS_LOG_PROC_INFO_SIZE} 
       ; Calculate start address of an element 
       IntOp $2 $2 - ${SYS_LOG_PROC_INFO_SIZE} 
       IntOp $3 $1 + $2 
       ; Get ProcessorMask value from element 
       System::Call "*$3(i.r4)" 
       Push $4 
       IntOp $3 $3 + ${RELATIONSHIP_OFFSET} 
       ; Get Relationship value from element 
       System::Call "*$3(i.r4)" 
       ${If} $4 == ${RELATIONPROCESSORCORE} 
           ; Increment Processor cores 
           IntOp $5 $5 + 1 
           ; Determine number of Logical Processor by counting the bits 
           ; set in the value of ProcessorMask 
           Call countbits 
           Pop $4 
           ; Sum up Logical Processors 
           IntOp $6 $6 + $4 
       ${Else} 
           Pop $4 
       ${EndIf} 
   ${EndWhile} 

   ; Set processor information as return value 
   StrCpy $0 $5

   Pop $6 
   Pop $5 
   Pop $4 
   Pop $3 
   Pop $2 
   Pop $1 
   Exch $0 
FunctionEnd 

; Get processor information 
; Returns: number of Processor Cores and Logical Processors 
Function getcpuinfo 
  Push $0 
  Push $1 
  Push $2 
  Push $3 
  Push $4 

  ; GetLogicalProcessorInformation is only available on  
  ; Windows XP SP3 or its successors. 

  ; Initialize buffer and its length 
  StrCpy $1 0 
  StrCpy $2 0 

  ; Determine required length of buffer 
  System::Call "kernel32::GetLogicalProcessorInformation(ir1, *ir2r2) i.r3 ? e" 
  Pop $4 
  ${If} $3 == 0 
     ${If} $4 == ${ERROR_INSUFFICIENT_BUFFER} 
         ; Allocate buffer 
         System::Alloc $2 
         Pop $1 
         ${If} $1 != 0 
             ; Get processor information 
             System::Call "kernel32::GetLogicalProcessorInformation(ir1, *ir2r2) i.r3 ? e" 
             Pop $4 
             ${If} $3 != 1 
                 StrCpy $0 "Error: $4" 
             ${Else} 
                 Push $1 ; buffer 
                 Push $2 ; length 
                 Call evalcpuinfo 
                 Pop $0 
             ${EndIf} 
             ; Deallocate buffer 
             System::Free $1 
         ${Else} 
             StrCpy $0 "Error: memory allocation failed!" 
         ${EndIf} 
     ${Else} 
         StrCpy $0 "Error: $4" 
     ${EndIf} 
  ${Else} 
     StrCpy $0 "GetLogicalProcessorInformation is not available on your system!" 
  ${EndIf} 

  Pop $4 
  Pop $3 
  Pop $2 
  Pop $1 
  Exch $0 
FunctionEnd  

我认为该代码与Anders代码非常相似。我已经在三台不同的电脑上试用过,得到了处理器核心的正确数字。

我怀疑它是否只返回第一个数字,更可能是CPU检测代码有问题……我只是浏览了源代码,但没有发现任何问题。该插件使用x264项目(2013年2月)中的类,但是2011版本中的限制已经是64个CPU:您能给我们提供更多信息吗?什么平台(Win、Linux、MACOS等?),您有什么确切的CPU(英特尔、AMD等),CPU的确切名称是什么(Opteron 6338P、Xeon E5-2697等)?@Lonzak平台是Win7,CPU是英特尔。当我检查计算机规格时,它显示6个核心和12个逻辑处理器。显然,CPUFeatures.GetCount将返回逻辑处理器编号,而不是核心。显然${CPUFeatures.GetCount}返回逻辑处理器编号,而不是处理器核心,因此我不再使用它。应用程序仅限于Win7和Win8。您为什么选择此选项而不是我的答案?我同时使用GetLogicalProcessorInformation和GetLogicalProcessorInformationEx,而您的代码仅限于64个核…为什么在使用GetLogicalProcessorInformation时还需要使用GetLogicalProcessorInformationEx?GetLogicalProcessorInformation的MSDN页面:“在具有64个以上逻辑处理器的系统上,GetLogicalProcessorInformation函数检索调用线程当前分配到的处理器组中处理器的逻辑处理器信息。使用GetLogicalProcessorInformationEx函数检索系统上所有处理器组中的处理器信息。”