I would like to be able to select which CPUs my IIS app pool is using. It is possible to set an Affinity Mask in the pool settings but I would like to be able to calculate the mask programmatically depending the available cores. For example run on all available cores except 1 and 2.
I wrote two helpers which convert the mask to a list of cpu numbers and a list of cpu numbers to a mask but it feels like I should be using bitwise operators. I am curious how you would do it, is there an easier way or if there are built in functions or modules I can use to achieve the same.
https://serverfault.com/questions/471105/formula-for-processor-affinity-mask-iis
My example:
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)
}
I tested my helpers by converting back and forth and checking if I get the same values.
[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))))
Well you can simplify Get-Mask without bitwise ops:
function Get-Mask($cpus) {
$cpus | Foreach -Begin {$mask=0} -Process {$mask += [Math]::Pow(2,$_)} -End {$mask}
}
In Get-Cpus you could use a shift-right to simplify. Normally I would just divide by 2 but PowerShell well return doubles for non-integer results.
function Get-Cpus($mask) {
for ($i=0; $mask -gt 0; $i++) {
if ($mask % 2 -eq 1) {
$i
}
$mask = $mask -shr 1
}
}
The "classic" way would be like this:
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
}
Instead of using [Math]::pow(2,x)
one can just do real left shift of 1, up to 64. Technically it'll be better that if there would be a 64 or more in $cpus
, an exception will be thrown.
"Easier" ways consist of the same operation, just compacted into a function somewhere.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.