如何使用Powershell计算应用程序池的处理器关联掩码?

时间:2015-07-17 15:54:10

标签: powershell iis bitwise-operators

我希望能够选择我的IIS应用程序池正在使用哪些CPU。可以在池设置中设置Affinity Mask,但我希望能够根据可用的核心以编程方式计算掩码。例如,在除1和2之外的所有可用核心上运行。

我编写了两个帮助程序,它们将掩码转换为cpu编号列表和一个cpu编号列表到掩码,但感觉我应该使用按位运算符。我很好奇你会怎么做,有更简单的方法,或者是否有内置的功能或模块,我可以使用它来实现相同的目的。

https://serverfault.com/questions/471105/formula-for-processor-affinity-mask-iis

我的例子:

function Get-Cpus($mask){

    $binary = [Convert]::ToString($mask,2).ToCharArray()
    $i = $binary.Length - 1
    $cpus = @()

    for(;$i -ge 0; $i--){
        if($binary[$i] -eq "1"){
            $cpus += $binary.Length - $i - 1
        }
    }

    return $cpus | Sort-Object
}

function Get-Mask($cpus){
    $cpus = $cpus | Sort-Object
    $i = $cpus[$cpus.Length -1]
    $binary = ""

    for(; $i -ge 0; $i--){
        if($cpus -contains $i){
            $binary += "1"
        }
        else{
            $binary += "0"
        }
    }

    return [Convert]::ToInt64($binary, 2)
} 

我通过来回转换并检查我是否获得相同的值来测试我的助手。

[string]::Join(",", (Get-Cpus ([Convert]::ToInt64("00000000111111111111000000000000", 2))))
[string]::Join(",", (Get-Cpus 4294967295))
[string]::Join(",", (Get-Cpus (Get-Mask 2,9,5,23,4,7,31)))
[string]::Join(",", (Get-Cpus (Get-Mask 2,4,5,7,9,23,31)))
[string]::Join(",", (Get-Cpus (Get-Mask 1,2,30,31)))
[string]::Join(",", (Get-Cpus (Get-Mask 30,2,1,31)))
[string]::Join(",", (Get-Cpus (Get-Mask @(0..31)))) 

2 个答案:

答案 0 :(得分:1)

你可以简化Get-Mask而不使用按位操作:

function Get-Mask($cpus) {
    $cpus | Foreach -Begin {$mask=0} -Process {$mask += [Math]::Pow(2,$_)} -End {$mask}
}

在Get-Cpus中,您可以使用右移来简化。通常情况下,我只会除以2,但PowerShell很好地返回非整数结果的双倍。

function Get-Cpus($mask) {
    for ($i=0; $mask -gt 0; $i++) {
        if ($mask % 2 -eq 1) {
            $i
        }
        $mask = $mask -shr 1
    }
}

答案 1 :(得分:1)

“经典”的方式是这样的:

function Get-CPUs { 
param([int64]$mask)
  $a=@()
  $i=0
  while ($mask -gt 0) {
    if ($mask -band 1 -gt 0) { $a+=$i}
    $i+=1
    $mask=$mask -shr 1
  } 
  return $a
}

function Get-Mask {
param ([int64[]] $cpus)
  $mask=0
  foreach ($cpu in $cpus) { $mask = $mask -bor (1 -shl $cpu)}
  return $mask
}

不是使用[Math]::pow(2,x),而是可以实现真正的左移1,最多为64.从技术上讲,如果$cpus中有64或更多,则会更好被抛出。

“更简单”的方式包括相同的操作,只是在某个地方压缩成一个函数。