Microsoft Hyper-V Virtual Machine Queuing is useful to maximize high-bandwidth network cards. However, configuring this feature correctly can be a challenge. In brief, here are some recommendations:
Use the right Adapter and driver – avoid Broadcom and older NICs- Assign enough processors to match desired bandwidth. A rule of thumb is that each processor core can handle about 3Gbps; thus, a 10Gbps NIC requires at least 4 cores to account for those cores being shared with system processes.
Common Network Adapter Information Gathering Commands:
get-netadaptervmq
get-netadaptervmq|select name,MaxProcessorNumber
get-vmhostnumanode
get-netAdapterHardwareInfo
Get-NetAdapterVmqQueue
Basic VMQ setting command:
Set-NetAdapterVmq -Name ‘Ethernet X’ -Enabled $True
Set-NetAdapterVmq -Name ‘Ethernet X’ -Enabled $False
# AssignProcessorToNic.ps1
# Assigning a NIC to certain Processor
$coresCount=$(get-WMIObject Win32_Processor | measure-object -Property NumberOfCores -sum).Sum
$processorsCount=(Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors
$isHyperThreadingEnabled=$processorsCount -gt $coresCount
$availableProcessors=$processorsCount-1
$10GPhysicalNics=Get-NetAdapter -Physical|?{[int]($_.LinkSpeed -replace '\D+') -ge 10}
#$10GPhysicalNics=Get-NetAdapter|?{[int]($_.LinkSpeed -replace '\D+') -ge 10}
$maxProcessorsPerNic=[math]::ceiling($availableProcessors/$10GPhysicalNics.Name.Count)
$initialProcessorNumber=1
foreach ($10GNic in $10GPhysicalNics){
$10GNicName=$10GNic.Name
$maxProcessors=.{
$minRecommended=[math]::ceiling([int]($10GNic.LinkSpeed -replace '\D+')/3);
if($maxProcessorsPerNic -gt $minRecommended){
$value=$maxProcessorsPerNic
}else{
$value=$minRecommended
}
if($isHyperThreadingEnabled){
if($value%2 -eq 0){$value}else{$value+1}
}
}
$command="Set-NetAdapterVmq -name '$10GNicName' -BaseProcessorNumber $initialProcessorNumber -MaxProcessorNumber $($initialProcessorNumber+$maxProcessors-1) -MaxProcessors $maxProcessors"
write-host $command
pause
#invoke-expression $command
$initialProcessorNumber+=$maxProcessors
Get-NetAdapterVmq -name $10GNicName
}
<#
Error:
Set-NetAdapterVmq : No matching keyword value found. The following are valid keyword values: 1, 2, 4, 8, 16
At line:1 char:1
+ Set-NetAdapterVmq -name 'Ethernet' -BaseProcessorNumber 1 -MaxProce ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (MSFT_NetAdapter...1FD6A0017D60}"):ROOT/StandardCi...rVmqSettingData) [Set-NetAdap
terVmq], CimException
+ FullyQualifiedErrorId : Windows System Error 87,Set-NetAdapterVmq
Get-NetAdapterVmq : No MSFT_NetAdapterVmqSettingData objects found with property 'Name' equal to '$10GNicName'. Verify the value
of the property and retry.
At line:15 char:5
+ Get-NetAdapterVmq -name '$10GNicName'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: ($10GNicName:String) [Get-NetAdapterVmq], CimJobException
+ FullyQualifiedErrorId : CmdletizationQuery_NotFound_Name,Get-NetAdapterVmq
Explanation:
VMQ will ignore Hyper-threaded cores. Thus, on systems where HT is enabled, CPU core number must be set as an
even number vs on HT-disabled systems where odd numbers can be assigned.
$cpuObject=get-WMIObject Win32_Processor
$isHyperThreadingEnabled=($cpuObject|measure-object -Property NumberOfLogicalProcessors -sum).Sum -gt $($cpuObject | measure-object -Property NumberOfCores -sum).Sum
#>