@@ -30,6 +30,12 @@ import (
3030// Objective:
3131// We want to maximize x_w, or, equivalently, minimize x_c
3232
33+ const (
34+ // x86 limit. 256 hardware entries, of those 32 reserved. 256-32 = 224.
35+ // see: https://en.wikipedia.org/wiki/Interrupt_request
36+ maxIRQsPerPhysicalCore int = 224
37+ )
38+
3339const (
3440 defaultPenaltyWeight float64 = 100.0
3541 defaultReservedRatioInitial float64 = 0.0625 // 1/16. determined empirically. Use only as initial value.
@@ -65,7 +71,7 @@ type Params struct {
6571}
6672
6773func (p Params ) String () string {
68- return fmt .Sprintf ("cpus=%d offline=%v SMTLevel=%v devices=%d (userNetworking=%v)" , p .totalCPUs , p .OfflinedCPUCount , p .smtLevel , p .DeviceCount , p .UserLevelNetworking )
74+ return fmt .Sprintf ("cpus=%d offline=%v SMTLevel=%v devices=%d (req=%v userNetworking=%v)" , p .totalCPUs , p .OfflinedCPUCount , p .smtLevel , p .DeviceCount , p . MinCPUs () , p .UserLevelNetworking )
6975}
7076
7177func setupMachineData (p * Params ) error {
@@ -82,6 +88,13 @@ func setupMachineData(p *Params) error {
8288 return nil
8389}
8490
91+ func (p Params ) MinCPUs () int {
92+ if ! p .UserLevelNetworking { // TODO explain why
93+ return 0
94+ }
95+ return (p .DeviceCount + (maxIRQsPerPhysicalCore - 1 )) / maxIRQsPerPhysicalCore
96+ }
97+
8598func (p Params ) TotalCPUs () int {
8699 return p .totalCPUs
87100}
@@ -193,6 +206,9 @@ func objective(p Params, x []float64) float64 {
193206 // Don't exceed total CPUs
194207 hardPenalty += defaultPenaltyWeight * math .Pow (math .Max (0 , x_c + x_w - float64 (p .TotalCPUs ())), 2 )
195208
209+ // Allocate as minimum what is needed to fit the desired amount of devices, thus IRQs
210+ hardPenalty += defaultPenaltyWeight * math .Pow (math .Max (0 , float64 (p .MinCPUs ())- x_c ), 2 )
211+
196212 // Meet the control plane/infra requirement to avoid the workload to starve
197213 hardPenalty += defaultPenaltyWeight * math .Pow (math .Max (0 , p .controlPlaneRequirement (x_w )- x_c ), 2 )
198214
0 commit comments