Virtual Machine Queue: Assigning Processors to Network Interfaces

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
#>

Leave a Reply

Your email address will not be published. Required fields are marked *