diff --git a/pkg/kubelet/cm/BUILD b/pkg/kubelet/cm/BUILD index 46f1c8fccd4..96aaa1996da 100644 --- a/pkg/kubelet/cm/BUILD +++ b/pkg/kubelet/cm/BUILD @@ -69,6 +69,7 @@ go_library( "//pkg/apis/core/v1/helper:go_default_library", "//pkg/apis/core/v1/helper/qos:go_default_library", "//pkg/kubelet/cadvisor:go_default_library", + "//pkg/kubelet/cm/cpumanager/topology:go_default_library", "//pkg/kubelet/cm/devicemanager:go_default_library", "//pkg/kubelet/cm/util:go_default_library", "//pkg/kubelet/events:go_default_library", diff --git a/pkg/kubelet/cm/container_manager_linux.go b/pkg/kubelet/cm/container_manager_linux.go index da651b7842d..5a171cee187 100644 --- a/pkg/kubelet/cm/container_manager_linux.go +++ b/pkg/kubelet/cm/container_manager_linux.go @@ -47,6 +47,7 @@ import ( podresourcesapi "k8s.io/kubernetes/pkg/kubelet/apis/podresources/v1alpha1" "k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager" + cputopology "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" "k8s.io/kubernetes/pkg/kubelet/cm/devicemanager" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" cmutil "k8s.io/kubernetes/pkg/kubelet/cm/util" @@ -226,6 +227,13 @@ func NewContainerManager(mountUtil mount.Interface, cadvisorInterface cadvisor.I if err != nil { return nil, err } + // Correct NUMA information is currently missing from cadvisor's + // MachineInfo struct, so we use the CPUManager's internal logic for + // gathering NUMANodeInfo to pass to components that care about it. + numaNodeInfo, err := cputopology.GetNUMANodeInfo() + if err != nil { + return nil, err + } capacity := cadvisor.CapacityFromMachineInfo(machineInfo) for k, v := range capacity { internalCapacity[k] = v @@ -309,6 +317,7 @@ func NewContainerManager(mountUtil mount.Interface, cadvisorInterface cadvisor.I nodeConfig.ExperimentalCPUManagerPolicy, nodeConfig.ExperimentalCPUManagerReconcilePeriod, machineInfo, + numaNodeInfo, cm.GetNodeAllocatableReservation(), nodeConfig.KubeletRootDir, cm.topologyManager, diff --git a/pkg/kubelet/cm/cpumanager/cpu_manager.go b/pkg/kubelet/cm/cpumanager/cpu_manager.go index a2059de09f3..0efe986ed88 100644 --- a/pkg/kubelet/cm/cpumanager/cpu_manager.go +++ b/pkg/kubelet/cm/cpumanager/cpu_manager.go @@ -94,7 +94,7 @@ type manager struct { // and the containerID of their containers podStatusProvider status.PodStatusProvider - machineInfo *cadvisorapi.MachineInfo + topology *topology.CPUTopology nodeAllocatableReservation v1.ResourceList } @@ -102,7 +102,8 @@ type manager struct { var _ Manager = &manager{} // NewManager creates new cpu manager based on provided policy -func NewManager(cpuPolicyName string, reconcilePeriod time.Duration, machineInfo *cadvisorapi.MachineInfo, nodeAllocatableReservation v1.ResourceList, stateFileDirectory string, affinity topologymanager.Store) (Manager, error) { +func NewManager(cpuPolicyName string, reconcilePeriod time.Duration, machineInfo *cadvisorapi.MachineInfo, numaNodeInfo topology.NUMANodeInfo, nodeAllocatableReservation v1.ResourceList, stateFileDirectory string, affinity topologymanager.Store) (Manager, error) { + var topo *topology.CPUTopology var policy Policy switch policyName(cpuPolicyName) { @@ -111,7 +112,8 @@ func NewManager(cpuPolicyName string, reconcilePeriod time.Duration, machineInfo policy = NewNonePolicy() case PolicyStatic: - topo, err := topology.Discover(machineInfo) + var err error + topo, err := topology.Discover(machineInfo, numaNodeInfo) if err != nil { return nil, err } @@ -149,7 +151,7 @@ func NewManager(cpuPolicyName string, reconcilePeriod time.Duration, machineInfo policy: policy, reconcilePeriod: reconcilePeriod, state: stateImpl, - machineInfo: machineInfo, + topology: topo, nodeAllocatableReservation: nodeAllocatableReservation, } return manager, nil diff --git a/pkg/kubelet/cm/cpumanager/cpu_manager_test.go b/pkg/kubelet/cm/cpumanager/cpu_manager_test.go index 404ceece252..92e5792fe3f 100644 --- a/pkg/kubelet/cm/cpumanager/cpu_manager_test.go +++ b/pkg/kubelet/cm/cpumanager/cpu_manager_test.go @@ -343,7 +343,7 @@ func TestCPUManagerGenerate(t *testing.T) { } defer os.RemoveAll(sDir) - mgr, err := NewManager(testCase.cpuPolicyName, 5*time.Second, machineInfo, testCase.nodeAllocatableReservation, sDir, topologymanager.NewFakeManager()) + mgr, err := NewManager(testCase.cpuPolicyName, 5*time.Second, machineInfo, nil, testCase.nodeAllocatableReservation, sDir, topologymanager.NewFakeManager()) if testCase.expectedError != nil { if !strings.Contains(err.Error(), testCase.expectedError.Error()) { t.Errorf("Unexpected error message. Have: %s wants %s", err.Error(), testCase.expectedError.Error()) diff --git a/pkg/kubelet/cm/cpumanager/policy_static.go b/pkg/kubelet/cm/cpumanager/policy_static.go index 90b214c55ab..7c05d976b29 100644 --- a/pkg/kubelet/cm/cpumanager/policy_static.go +++ b/pkg/kubelet/cm/cpumanager/policy_static.go @@ -220,8 +220,8 @@ func (p *staticPolicy) AddContainer(s state.State, pod *v1.Pod, container *v1.Co hint := p.affinity.GetAffinity(string(pod.UID), container.Name) klog.Infof("[cpumanager] Pod %v, Container %v Topology Affinity is: %v", pod.UID, container.Name, hint) - // Allocate CPUs according to the socket affinity contained in the hint. - cpuset, err := p.allocateCPUs(s, numCPUs, hint.SocketAffinity) + // Allocate CPUs according to the NUMA affinity contained in the hint. + cpuset, err := p.allocateCPUs(s, numCPUs, hint.NUMANodeAffinity) if err != nil { klog.Errorf("[cpumanager] unable to allocate %d CPUs (container id: %s, error: %v)", numCPUs, containerID, err) return err @@ -250,15 +250,15 @@ func (p *staticPolicy) RemoveContainer(s state.State, containerID string) (rerr return nil } -func (p *staticPolicy) allocateCPUs(s state.State, numCPUs int, socketmask socketmask.SocketMask) (cpuset.CPUSet, error) { - klog.Infof("[cpumanager] allocateCpus: (numCPUs: %d, socket: %v)", numCPUs, socketmask) +func (p *staticPolicy) allocateCPUs(s state.State, numCPUs int, numaAffinity socketmask.SocketMask) (cpuset.CPUSet, error) { + klog.Infof("[cpumanager] allocateCpus: (numCPUs: %d, socket: %v)", numCPUs, numaAffinity) - // If there are aligned CPUs in the socketmask, attempt to take those first. + // If there are aligned CPUs in numaAffinity, attempt to take those first. result := cpuset.NewCPUSet() - if socketmask != nil { + if numaAffinity != nil { alignedCPUs := cpuset.NewCPUSet() - for _, socketID := range socketmask.GetSockets() { - alignedCPUs = alignedCPUs.Union(p.assignableCPUs(s).Intersection(p.topology.CPUDetails.CPUsInSocket(socketID))) + for _, numaNodeID := range numaAffinity.GetSockets() { + alignedCPUs = alignedCPUs.Union(p.assignableCPUs(s).Intersection(p.topology.CPUDetails.CPUsInNUMANode(numaNodeID))) } numAlignedToAlloc := alignedCPUs.Size() diff --git a/pkg/kubelet/cm/cpumanager/policy_test.go b/pkg/kubelet/cm/cpumanager/policy_test.go index c8d3c6b8276..02e3709c01d 100644 --- a/pkg/kubelet/cm/cpumanager/policy_test.go +++ b/pkg/kubelet/cm/cpumanager/policy_test.go @@ -26,14 +26,14 @@ var ( NumSockets: 1, NumCores: 4, CPUDetails: map[int]topology.CPUInfo{ - 0: {CoreID: 0, SocketID: 0}, - 1: {CoreID: 1, SocketID: 0}, - 2: {CoreID: 2, SocketID: 0}, - 3: {CoreID: 3, SocketID: 0}, - 4: {CoreID: 0, SocketID: 0}, - 5: {CoreID: 1, SocketID: 0}, - 6: {CoreID: 2, SocketID: 0}, - 7: {CoreID: 3, SocketID: 0}, + 0: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 1: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 2: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 3: {CoreID: 3, SocketID: 0, NUMANodeID: 0}, + 4: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 5: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 6: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 7: {CoreID: 3, SocketID: 0, NUMANodeID: 0}, }, } @@ -42,18 +42,18 @@ var ( NumSockets: 2, NumCores: 6, CPUDetails: map[int]topology.CPUInfo{ - 0: {CoreID: 0, SocketID: 0}, - 1: {CoreID: 1, SocketID: 1}, - 2: {CoreID: 2, SocketID: 0}, - 3: {CoreID: 3, SocketID: 1}, - 4: {CoreID: 4, SocketID: 0}, - 5: {CoreID: 5, SocketID: 1}, - 6: {CoreID: 0, SocketID: 0}, - 7: {CoreID: 1, SocketID: 1}, - 8: {CoreID: 2, SocketID: 0}, - 9: {CoreID: 3, SocketID: 1}, - 10: {CoreID: 4, SocketID: 0}, - 11: {CoreID: 5, SocketID: 1}, + 0: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 1: {CoreID: 1, SocketID: 1, NUMANodeID: 1}, + 2: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 3: {CoreID: 3, SocketID: 1, NUMANodeID: 1}, + 4: {CoreID: 4, SocketID: 0, NUMANodeID: 0}, + 5: {CoreID: 5, SocketID: 1, NUMANodeID: 1}, + 6: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 7: {CoreID: 1, SocketID: 1, NUMANodeID: 1}, + 8: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 9: {CoreID: 3, SocketID: 1, NUMANodeID: 1}, + 10: {CoreID: 4, SocketID: 0, NUMANodeID: 0}, + 11: {CoreID: 5, SocketID: 1, NUMANodeID: 1}, }, } @@ -62,14 +62,14 @@ var ( NumSockets: 2, NumCores: 8, CPUDetails: map[int]topology.CPUInfo{ - 0: {CoreID: 0, SocketID: 0}, - 1: {CoreID: 1, SocketID: 0}, - 2: {CoreID: 2, SocketID: 0}, - 3: {CoreID: 3, SocketID: 0}, - 4: {CoreID: 4, SocketID: 1}, - 5: {CoreID: 5, SocketID: 1}, - 6: {CoreID: 6, SocketID: 1}, - 7: {CoreID: 7, SocketID: 1}, + 0: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 1: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 2: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 3: {CoreID: 3, SocketID: 0, NUMANodeID: 0}, + 4: {CoreID: 4, SocketID: 1, NUMANodeID: 1}, + 5: {CoreID: 5, SocketID: 1, NUMANodeID: 1}, + 6: {CoreID: 6, SocketID: 1, NUMANodeID: 1}, + 7: {CoreID: 7, SocketID: 1, NUMANodeID: 1}, }, } @@ -97,294 +97,294 @@ var ( NumSockets: 4, NumCores: 72, CPUDetails: map[int]topology.CPUInfo{ - 0: {CoreID: 0, SocketID: 0}, - 169: {CoreID: 0, SocketID: 0}, - 109: {CoreID: 0, SocketID: 0}, - 229: {CoreID: 0, SocketID: 0}, - 50: {CoreID: 1, SocketID: 0}, - 170: {CoreID: 1, SocketID: 0}, - 110: {CoreID: 1, SocketID: 0}, - 230: {CoreID: 1, SocketID: 0}, - 1: {CoreID: 64, SocketID: 0}, - 25: {CoreID: 64, SocketID: 0}, - 13: {CoreID: 64, SocketID: 0}, - 38: {CoreID: 64, SocketID: 0}, - 2: {CoreID: 65, SocketID: 0}, - 26: {CoreID: 65, SocketID: 0}, - 14: {CoreID: 65, SocketID: 0}, - 39: {CoreID: 65, SocketID: 0}, - 9: {CoreID: 72, SocketID: 0}, - 33: {CoreID: 72, SocketID: 0}, - 21: {CoreID: 72, SocketID: 0}, - 46: {CoreID: 72, SocketID: 0}, - 10: {CoreID: 73, SocketID: 0}, - 34: {CoreID: 73, SocketID: 0}, - 22: {CoreID: 73, SocketID: 0}, - 47: {CoreID: 73, SocketID: 0}, - 57: {CoreID: 8, SocketID: 0}, - 177: {CoreID: 8, SocketID: 0}, - 117: {CoreID: 8, SocketID: 0}, - 237: {CoreID: 8, SocketID: 0}, - 58: {CoreID: 9, SocketID: 0}, - 178: {CoreID: 9, SocketID: 0}, - 118: {CoreID: 9, SocketID: 0}, - 238: {CoreID: 9, SocketID: 0}, - 71: {CoreID: 24, SocketID: 0}, - 191: {CoreID: 24, SocketID: 0}, - 131: {CoreID: 24, SocketID: 0}, - 251: {CoreID: 24, SocketID: 0}, - 72: {CoreID: 25, SocketID: 0}, - 192: {CoreID: 25, SocketID: 0}, - 132: {CoreID: 25, SocketID: 0}, - 252: {CoreID: 25, SocketID: 0}, - 79: {CoreID: 32, SocketID: 0}, - 199: {CoreID: 32, SocketID: 0}, - 139: {CoreID: 32, SocketID: 0}, - 259: {CoreID: 32, SocketID: 0}, - 80: {CoreID: 33, SocketID: 0}, - 200: {CoreID: 33, SocketID: 0}, - 140: {CoreID: 33, SocketID: 0}, - 260: {CoreID: 33, SocketID: 0}, - 87: {CoreID: 40, SocketID: 0}, - 207: {CoreID: 40, SocketID: 0}, - 147: {CoreID: 40, SocketID: 0}, - 267: {CoreID: 40, SocketID: 0}, - 88: {CoreID: 41, SocketID: 0}, - 208: {CoreID: 41, SocketID: 0}, - 148: {CoreID: 41, SocketID: 0}, - 268: {CoreID: 41, SocketID: 0}, - 95: {CoreID: 48, SocketID: 0}, - 215: {CoreID: 48, SocketID: 0}, - 155: {CoreID: 48, SocketID: 0}, - 275: {CoreID: 48, SocketID: 0}, - 96: {CoreID: 49, SocketID: 0}, - 216: {CoreID: 49, SocketID: 0}, - 156: {CoreID: 49, SocketID: 0}, - 276: {CoreID: 49, SocketID: 0}, - 103: {CoreID: 56, SocketID: 0}, - 223: {CoreID: 56, SocketID: 0}, - 163: {CoreID: 56, SocketID: 0}, - 283: {CoreID: 56, SocketID: 0}, - 104: {CoreID: 57, SocketID: 0}, - 224: {CoreID: 57, SocketID: 0}, - 164: {CoreID: 57, SocketID: 0}, - 284: {CoreID: 57, SocketID: 0}, - 3: {CoreID: 66, SocketID: 1}, - 27: {CoreID: 66, SocketID: 1}, - 15: {CoreID: 66, SocketID: 1}, - 40: {CoreID: 66, SocketID: 1}, - 4: {CoreID: 67, SocketID: 1}, - 28: {CoreID: 67, SocketID: 1}, - 16: {CoreID: 67, SocketID: 1}, - 41: {CoreID: 67, SocketID: 1}, - 11: {CoreID: 74, SocketID: 1}, - 35: {CoreID: 74, SocketID: 1}, - 23: {CoreID: 74, SocketID: 1}, - 48: {CoreID: 74, SocketID: 1}, - 12: {CoreID: 75, SocketID: 1}, - 36: {CoreID: 75, SocketID: 1}, - 24: {CoreID: 75, SocketID: 1}, - 49: {CoreID: 75, SocketID: 1}, - 51: {CoreID: 2, SocketID: 1}, - 171: {CoreID: 2, SocketID: 1}, - 111: {CoreID: 2, SocketID: 1}, - 231: {CoreID: 2, SocketID: 1}, - 52: {CoreID: 3, SocketID: 1}, - 172: {CoreID: 3, SocketID: 1}, - 112: {CoreID: 3, SocketID: 1}, - 232: {CoreID: 3, SocketID: 1}, - 59: {CoreID: 10, SocketID: 1}, - 179: {CoreID: 10, SocketID: 1}, - 119: {CoreID: 10, SocketID: 1}, - 239: {CoreID: 10, SocketID: 1}, - 60: {CoreID: 11, SocketID: 1}, - 180: {CoreID: 11, SocketID: 1}, - 120: {CoreID: 11, SocketID: 1}, - 240: {CoreID: 11, SocketID: 1}, - 65: {CoreID: 18, SocketID: 1}, - 185: {CoreID: 18, SocketID: 1}, - 125: {CoreID: 18, SocketID: 1}, - 245: {CoreID: 18, SocketID: 1}, - 66: {CoreID: 19, SocketID: 1}, - 186: {CoreID: 19, SocketID: 1}, - 126: {CoreID: 19, SocketID: 1}, - 246: {CoreID: 19, SocketID: 1}, - 73: {CoreID: 26, SocketID: 1}, - 193: {CoreID: 26, SocketID: 1}, - 133: {CoreID: 26, SocketID: 1}, - 253: {CoreID: 26, SocketID: 1}, - 74: {CoreID: 27, SocketID: 1}, - 194: {CoreID: 27, SocketID: 1}, - 134: {CoreID: 27, SocketID: 1}, - 254: {CoreID: 27, SocketID: 1}, - 81: {CoreID: 34, SocketID: 1}, - 201: {CoreID: 34, SocketID: 1}, - 141: {CoreID: 34, SocketID: 1}, - 261: {CoreID: 34, SocketID: 1}, - 82: {CoreID: 35, SocketID: 1}, - 202: {CoreID: 35, SocketID: 1}, - 142: {CoreID: 35, SocketID: 1}, - 262: {CoreID: 35, SocketID: 1}, - 89: {CoreID: 42, SocketID: 1}, - 209: {CoreID: 42, SocketID: 1}, - 149: {CoreID: 42, SocketID: 1}, - 269: {CoreID: 42, SocketID: 1}, - 90: {CoreID: 43, SocketID: 1}, - 210: {CoreID: 43, SocketID: 1}, - 150: {CoreID: 43, SocketID: 1}, - 270: {CoreID: 43, SocketID: 1}, - 97: {CoreID: 50, SocketID: 1}, - 217: {CoreID: 50, SocketID: 1}, - 157: {CoreID: 50, SocketID: 1}, - 277: {CoreID: 50, SocketID: 1}, - 98: {CoreID: 51, SocketID: 1}, - 218: {CoreID: 51, SocketID: 1}, - 158: {CoreID: 51, SocketID: 1}, - 278: {CoreID: 51, SocketID: 1}, - 5: {CoreID: 68, SocketID: 2}, - 29: {CoreID: 68, SocketID: 2}, - 17: {CoreID: 68, SocketID: 2}, - 42: {CoreID: 68, SocketID: 2}, - 6: {CoreID: 69, SocketID: 2}, - 30: {CoreID: 69, SocketID: 2}, - 18: {CoreID: 69, SocketID: 2}, - 43: {CoreID: 69, SocketID: 2}, - 53: {CoreID: 4, SocketID: 2}, - 173: {CoreID: 4, SocketID: 2}, - 113: {CoreID: 4, SocketID: 2}, - 233: {CoreID: 4, SocketID: 2}, - 54: {CoreID: 5, SocketID: 2}, - 174: {CoreID: 5, SocketID: 2}, - 114: {CoreID: 5, SocketID: 2}, - 234: {CoreID: 5, SocketID: 2}, - 61: {CoreID: 12, SocketID: 2}, - 181: {CoreID: 12, SocketID: 2}, - 121: {CoreID: 12, SocketID: 2}, - 241: {CoreID: 12, SocketID: 2}, - 62: {CoreID: 13, SocketID: 2}, - 182: {CoreID: 13, SocketID: 2}, - 122: {CoreID: 13, SocketID: 2}, - 242: {CoreID: 13, SocketID: 2}, - 67: {CoreID: 20, SocketID: 2}, - 187: {CoreID: 20, SocketID: 2}, - 127: {CoreID: 20, SocketID: 2}, - 247: {CoreID: 20, SocketID: 2}, - 68: {CoreID: 21, SocketID: 2}, - 188: {CoreID: 21, SocketID: 2}, - 128: {CoreID: 21, SocketID: 2}, - 248: {CoreID: 21, SocketID: 2}, - 75: {CoreID: 28, SocketID: 2}, - 195: {CoreID: 28, SocketID: 2}, - 135: {CoreID: 28, SocketID: 2}, - 255: {CoreID: 28, SocketID: 2}, - 76: {CoreID: 29, SocketID: 2}, - 196: {CoreID: 29, SocketID: 2}, - 136: {CoreID: 29, SocketID: 2}, - 256: {CoreID: 29, SocketID: 2}, - 83: {CoreID: 36, SocketID: 2}, - 203: {CoreID: 36, SocketID: 2}, - 143: {CoreID: 36, SocketID: 2}, - 263: {CoreID: 36, SocketID: 2}, - 84: {CoreID: 37, SocketID: 2}, - 204: {CoreID: 37, SocketID: 2}, - 144: {CoreID: 37, SocketID: 2}, - 264: {CoreID: 37, SocketID: 2}, - 91: {CoreID: 44, SocketID: 2}, - 211: {CoreID: 44, SocketID: 2}, - 151: {CoreID: 44, SocketID: 2}, - 271: {CoreID: 44, SocketID: 2}, - 92: {CoreID: 45, SocketID: 2}, - 212: {CoreID: 45, SocketID: 2}, - 152: {CoreID: 45, SocketID: 2}, - 272: {CoreID: 45, SocketID: 2}, - 99: {CoreID: 52, SocketID: 2}, - 219: {CoreID: 52, SocketID: 2}, - 159: {CoreID: 52, SocketID: 2}, - 279: {CoreID: 52, SocketID: 2}, - 100: {CoreID: 53, SocketID: 2}, - 220: {CoreID: 53, SocketID: 2}, - 160: {CoreID: 53, SocketID: 2}, - 280: {CoreID: 53, SocketID: 2}, - 105: {CoreID: 60, SocketID: 2}, - 225: {CoreID: 60, SocketID: 2}, - 165: {CoreID: 60, SocketID: 2}, - 285: {CoreID: 60, SocketID: 2}, - 106: {CoreID: 61, SocketID: 2}, - 226: {CoreID: 61, SocketID: 2}, - 166: {CoreID: 61, SocketID: 2}, - 286: {CoreID: 61, SocketID: 2}, - 7: {CoreID: 70, SocketID: 3}, - 31: {CoreID: 70, SocketID: 3}, - 19: {CoreID: 70, SocketID: 3}, - 44: {CoreID: 70, SocketID: 3}, - 8: {CoreID: 71, SocketID: 3}, - 32: {CoreID: 71, SocketID: 3}, - 20: {CoreID: 71, SocketID: 3}, - 45: {CoreID: 71, SocketID: 3}, - 37: {CoreID: 63, SocketID: 3}, - 168: {CoreID: 63, SocketID: 3}, - 108: {CoreID: 63, SocketID: 3}, - 228: {CoreID: 63, SocketID: 3}, - 107: {CoreID: 62, SocketID: 3}, - 227: {CoreID: 62, SocketID: 3}, - 167: {CoreID: 62, SocketID: 3}, - 287: {CoreID: 62, SocketID: 3}, - 55: {CoreID: 6, SocketID: 3}, - 175: {CoreID: 6, SocketID: 3}, - 115: {CoreID: 6, SocketID: 3}, - 235: {CoreID: 6, SocketID: 3}, - 56: {CoreID: 7, SocketID: 3}, - 176: {CoreID: 7, SocketID: 3}, - 116: {CoreID: 7, SocketID: 3}, - 236: {CoreID: 7, SocketID: 3}, - 63: {CoreID: 14, SocketID: 3}, - 183: {CoreID: 14, SocketID: 3}, - 123: {CoreID: 14, SocketID: 3}, - 243: {CoreID: 14, SocketID: 3}, - 64: {CoreID: 15, SocketID: 3}, - 184: {CoreID: 15, SocketID: 3}, - 124: {CoreID: 15, SocketID: 3}, - 244: {CoreID: 15, SocketID: 3}, - 69: {CoreID: 22, SocketID: 3}, - 189: {CoreID: 22, SocketID: 3}, - 129: {CoreID: 22, SocketID: 3}, - 249: {CoreID: 22, SocketID: 3}, - 70: {CoreID: 23, SocketID: 3}, - 190: {CoreID: 23, SocketID: 3}, - 130: {CoreID: 23, SocketID: 3}, - 250: {CoreID: 23, SocketID: 3}, - 77: {CoreID: 30, SocketID: 3}, - 197: {CoreID: 30, SocketID: 3}, - 137: {CoreID: 30, SocketID: 3}, - 257: {CoreID: 30, SocketID: 3}, - 78: {CoreID: 31, SocketID: 3}, - 198: {CoreID: 31, SocketID: 3}, - 138: {CoreID: 31, SocketID: 3}, - 258: {CoreID: 31, SocketID: 3}, - 85: {CoreID: 38, SocketID: 3}, - 205: {CoreID: 38, SocketID: 3}, - 145: {CoreID: 38, SocketID: 3}, - 265: {CoreID: 38, SocketID: 3}, - 86: {CoreID: 39, SocketID: 3}, - 206: {CoreID: 39, SocketID: 3}, - 146: {CoreID: 39, SocketID: 3}, - 266: {CoreID: 39, SocketID: 3}, - 93: {CoreID: 46, SocketID: 3}, - 213: {CoreID: 46, SocketID: 3}, - 153: {CoreID: 46, SocketID: 3}, - 273: {CoreID: 46, SocketID: 3}, - 94: {CoreID: 47, SocketID: 3}, - 214: {CoreID: 47, SocketID: 3}, - 154: {CoreID: 47, SocketID: 3}, - 274: {CoreID: 47, SocketID: 3}, - 101: {CoreID: 54, SocketID: 3}, - 221: {CoreID: 54, SocketID: 3}, - 161: {CoreID: 54, SocketID: 3}, - 281: {CoreID: 54, SocketID: 3}, - 102: {CoreID: 55, SocketID: 3}, - 222: {CoreID: 55, SocketID: 3}, - 162: {CoreID: 55, SocketID: 3}, - 282: {CoreID: 55, SocketID: 3}, + 0: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 169: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 109: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 229: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 50: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 170: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 110: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 230: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 1: {CoreID: 64, SocketID: 0, NUMANodeID: 0}, + 25: {CoreID: 64, SocketID: 0, NUMANodeID: 0}, + 13: {CoreID: 64, SocketID: 0, NUMANodeID: 0}, + 38: {CoreID: 64, SocketID: 0, NUMANodeID: 0}, + 2: {CoreID: 65, SocketID: 0, NUMANodeID: 0}, + 26: {CoreID: 65, SocketID: 0, NUMANodeID: 0}, + 14: {CoreID: 65, SocketID: 0, NUMANodeID: 0}, + 39: {CoreID: 65, SocketID: 0, NUMANodeID: 0}, + 9: {CoreID: 72, SocketID: 0, NUMANodeID: 0}, + 33: {CoreID: 72, SocketID: 0, NUMANodeID: 0}, + 21: {CoreID: 72, SocketID: 0, NUMANodeID: 0}, + 46: {CoreID: 72, SocketID: 0, NUMANodeID: 0}, + 10: {CoreID: 73, SocketID: 0, NUMANodeID: 0}, + 34: {CoreID: 73, SocketID: 0, NUMANodeID: 0}, + 22: {CoreID: 73, SocketID: 0, NUMANodeID: 0}, + 47: {CoreID: 73, SocketID: 0, NUMANodeID: 0}, + 57: {CoreID: 8, SocketID: 0, NUMANodeID: 0}, + 177: {CoreID: 8, SocketID: 0, NUMANodeID: 0}, + 117: {CoreID: 8, SocketID: 0, NUMANodeID: 0}, + 237: {CoreID: 8, SocketID: 0, NUMANodeID: 0}, + 58: {CoreID: 9, SocketID: 0, NUMANodeID: 0}, + 178: {CoreID: 9, SocketID: 0, NUMANodeID: 0}, + 118: {CoreID: 9, SocketID: 0, NUMANodeID: 0}, + 238: {CoreID: 9, SocketID: 0, NUMANodeID: 0}, + 71: {CoreID: 24, SocketID: 0, NUMANodeID: 0}, + 191: {CoreID: 24, SocketID: 0, NUMANodeID: 0}, + 131: {CoreID: 24, SocketID: 0, NUMANodeID: 0}, + 251: {CoreID: 24, SocketID: 0, NUMANodeID: 0}, + 72: {CoreID: 25, SocketID: 0, NUMANodeID: 0}, + 192: {CoreID: 25, SocketID: 0, NUMANodeID: 0}, + 132: {CoreID: 25, SocketID: 0, NUMANodeID: 0}, + 252: {CoreID: 25, SocketID: 0, NUMANodeID: 0}, + 79: {CoreID: 32, SocketID: 0, NUMANodeID: 0}, + 199: {CoreID: 32, SocketID: 0, NUMANodeID: 0}, + 139: {CoreID: 32, SocketID: 0, NUMANodeID: 0}, + 259: {CoreID: 32, SocketID: 0, NUMANodeID: 0}, + 80: {CoreID: 33, SocketID: 0, NUMANodeID: 0}, + 200: {CoreID: 33, SocketID: 0, NUMANodeID: 0}, + 140: {CoreID: 33, SocketID: 0, NUMANodeID: 0}, + 260: {CoreID: 33, SocketID: 0, NUMANodeID: 0}, + 87: {CoreID: 40, SocketID: 0, NUMANodeID: 0}, + 207: {CoreID: 40, SocketID: 0, NUMANodeID: 0}, + 147: {CoreID: 40, SocketID: 0, NUMANodeID: 0}, + 267: {CoreID: 40, SocketID: 0, NUMANodeID: 0}, + 88: {CoreID: 41, SocketID: 0, NUMANodeID: 0}, + 208: {CoreID: 41, SocketID: 0, NUMANodeID: 0}, + 148: {CoreID: 41, SocketID: 0, NUMANodeID: 0}, + 268: {CoreID: 41, SocketID: 0, NUMANodeID: 0}, + 95: {CoreID: 48, SocketID: 0, NUMANodeID: 0}, + 215: {CoreID: 48, SocketID: 0, NUMANodeID: 0}, + 155: {CoreID: 48, SocketID: 0, NUMANodeID: 0}, + 275: {CoreID: 48, SocketID: 0, NUMANodeID: 0}, + 96: {CoreID: 49, SocketID: 0, NUMANodeID: 0}, + 216: {CoreID: 49, SocketID: 0, NUMANodeID: 0}, + 156: {CoreID: 49, SocketID: 0, NUMANodeID: 0}, + 276: {CoreID: 49, SocketID: 0, NUMANodeID: 0}, + 103: {CoreID: 56, SocketID: 0, NUMANodeID: 0}, + 223: {CoreID: 56, SocketID: 0, NUMANodeID: 0}, + 163: {CoreID: 56, SocketID: 0, NUMANodeID: 0}, + 283: {CoreID: 56, SocketID: 0, NUMANodeID: 0}, + 104: {CoreID: 57, SocketID: 0, NUMANodeID: 0}, + 224: {CoreID: 57, SocketID: 0, NUMANodeID: 0}, + 164: {CoreID: 57, SocketID: 0, NUMANodeID: 0}, + 284: {CoreID: 57, SocketID: 0, NUMANodeID: 0}, + 3: {CoreID: 66, SocketID: 1, NUMANodeID: 1}, + 27: {CoreID: 66, SocketID: 1, NUMANodeID: 1}, + 15: {CoreID: 66, SocketID: 1, NUMANodeID: 1}, + 40: {CoreID: 66, SocketID: 1, NUMANodeID: 1}, + 4: {CoreID: 67, SocketID: 1, NUMANodeID: 1}, + 28: {CoreID: 67, SocketID: 1, NUMANodeID: 1}, + 16: {CoreID: 67, SocketID: 1, NUMANodeID: 1}, + 41: {CoreID: 67, SocketID: 1, NUMANodeID: 1}, + 11: {CoreID: 74, SocketID: 1, NUMANodeID: 1}, + 35: {CoreID: 74, SocketID: 1, NUMANodeID: 1}, + 23: {CoreID: 74, SocketID: 1, NUMANodeID: 1}, + 48: {CoreID: 74, SocketID: 1, NUMANodeID: 1}, + 12: {CoreID: 75, SocketID: 1, NUMANodeID: 1}, + 36: {CoreID: 75, SocketID: 1, NUMANodeID: 1}, + 24: {CoreID: 75, SocketID: 1, NUMANodeID: 1}, + 49: {CoreID: 75, SocketID: 1, NUMANodeID: 1}, + 51: {CoreID: 2, SocketID: 1, NUMANodeID: 1}, + 171: {CoreID: 2, SocketID: 1, NUMANodeID: 1}, + 111: {CoreID: 2, SocketID: 1, NUMANodeID: 1}, + 231: {CoreID: 2, SocketID: 1, NUMANodeID: 1}, + 52: {CoreID: 3, SocketID: 1, NUMANodeID: 1}, + 172: {CoreID: 3, SocketID: 1, NUMANodeID: 1}, + 112: {CoreID: 3, SocketID: 1, NUMANodeID: 1}, + 232: {CoreID: 3, SocketID: 1, NUMANodeID: 1}, + 59: {CoreID: 10, SocketID: 1, NUMANodeID: 1}, + 179: {CoreID: 10, SocketID: 1, NUMANodeID: 1}, + 119: {CoreID: 10, SocketID: 1, NUMANodeID: 1}, + 239: {CoreID: 10, SocketID: 1, NUMANodeID: 1}, + 60: {CoreID: 11, SocketID: 1, NUMANodeID: 1}, + 180: {CoreID: 11, SocketID: 1, NUMANodeID: 1}, + 120: {CoreID: 11, SocketID: 1, NUMANodeID: 1}, + 240: {CoreID: 11, SocketID: 1, NUMANodeID: 1}, + 65: {CoreID: 18, SocketID: 1, NUMANodeID: 1}, + 185: {CoreID: 18, SocketID: 1, NUMANodeID: 1}, + 125: {CoreID: 18, SocketID: 1, NUMANodeID: 1}, + 245: {CoreID: 18, SocketID: 1, NUMANodeID: 1}, + 66: {CoreID: 19, SocketID: 1, NUMANodeID: 1}, + 186: {CoreID: 19, SocketID: 1, NUMANodeID: 1}, + 126: {CoreID: 19, SocketID: 1, NUMANodeID: 1}, + 246: {CoreID: 19, SocketID: 1, NUMANodeID: 1}, + 73: {CoreID: 26, SocketID: 1, NUMANodeID: 1}, + 193: {CoreID: 26, SocketID: 1, NUMANodeID: 1}, + 133: {CoreID: 26, SocketID: 1, NUMANodeID: 1}, + 253: {CoreID: 26, SocketID: 1, NUMANodeID: 1}, + 74: {CoreID: 27, SocketID: 1, NUMANodeID: 1}, + 194: {CoreID: 27, SocketID: 1, NUMANodeID: 1}, + 134: {CoreID: 27, SocketID: 1, NUMANodeID: 1}, + 254: {CoreID: 27, SocketID: 1, NUMANodeID: 1}, + 81: {CoreID: 34, SocketID: 1, NUMANodeID: 1}, + 201: {CoreID: 34, SocketID: 1, NUMANodeID: 1}, + 141: {CoreID: 34, SocketID: 1, NUMANodeID: 1}, + 261: {CoreID: 34, SocketID: 1, NUMANodeID: 1}, + 82: {CoreID: 35, SocketID: 1, NUMANodeID: 1}, + 202: {CoreID: 35, SocketID: 1, NUMANodeID: 1}, + 142: {CoreID: 35, SocketID: 1, NUMANodeID: 1}, + 262: {CoreID: 35, SocketID: 1, NUMANodeID: 1}, + 89: {CoreID: 42, SocketID: 1, NUMANodeID: 1}, + 209: {CoreID: 42, SocketID: 1, NUMANodeID: 1}, + 149: {CoreID: 42, SocketID: 1, NUMANodeID: 1}, + 269: {CoreID: 42, SocketID: 1, NUMANodeID: 1}, + 90: {CoreID: 43, SocketID: 1, NUMANodeID: 1}, + 210: {CoreID: 43, SocketID: 1, NUMANodeID: 1}, + 150: {CoreID: 43, SocketID: 1, NUMANodeID: 1}, + 270: {CoreID: 43, SocketID: 1, NUMANodeID: 1}, + 97: {CoreID: 50, SocketID: 1, NUMANodeID: 1}, + 217: {CoreID: 50, SocketID: 1, NUMANodeID: 1}, + 157: {CoreID: 50, SocketID: 1, NUMANodeID: 1}, + 277: {CoreID: 50, SocketID: 1, NUMANodeID: 1}, + 98: {CoreID: 51, SocketID: 1, NUMANodeID: 1}, + 218: {CoreID: 51, SocketID: 1, NUMANodeID: 1}, + 158: {CoreID: 51, SocketID: 1, NUMANodeID: 1}, + 278: {CoreID: 51, SocketID: 1, NUMANodeID: 1}, + 5: {CoreID: 68, SocketID: 2, NUMANodeID: 2}, + 29: {CoreID: 68, SocketID: 2, NUMANodeID: 2}, + 17: {CoreID: 68, SocketID: 2, NUMANodeID: 2}, + 42: {CoreID: 68, SocketID: 2, NUMANodeID: 2}, + 6: {CoreID: 69, SocketID: 2, NUMANodeID: 2}, + 30: {CoreID: 69, SocketID: 2, NUMANodeID: 2}, + 18: {CoreID: 69, SocketID: 2, NUMANodeID: 2}, + 43: {CoreID: 69, SocketID: 2, NUMANodeID: 2}, + 53: {CoreID: 4, SocketID: 2, NUMANodeID: 2}, + 173: {CoreID: 4, SocketID: 2, NUMANodeID: 2}, + 113: {CoreID: 4, SocketID: 2, NUMANodeID: 2}, + 233: {CoreID: 4, SocketID: 2, NUMANodeID: 2}, + 54: {CoreID: 5, SocketID: 2, NUMANodeID: 2}, + 174: {CoreID: 5, SocketID: 2, NUMANodeID: 2}, + 114: {CoreID: 5, SocketID: 2, NUMANodeID: 2}, + 234: {CoreID: 5, SocketID: 2, NUMANodeID: 2}, + 61: {CoreID: 12, SocketID: 2, NUMANodeID: 2}, + 181: {CoreID: 12, SocketID: 2, NUMANodeID: 2}, + 121: {CoreID: 12, SocketID: 2, NUMANodeID: 2}, + 241: {CoreID: 12, SocketID: 2, NUMANodeID: 2}, + 62: {CoreID: 13, SocketID: 2, NUMANodeID: 2}, + 182: {CoreID: 13, SocketID: 2, NUMANodeID: 2}, + 122: {CoreID: 13, SocketID: 2, NUMANodeID: 2}, + 242: {CoreID: 13, SocketID: 2, NUMANodeID: 2}, + 67: {CoreID: 20, SocketID: 2, NUMANodeID: 2}, + 187: {CoreID: 20, SocketID: 2, NUMANodeID: 2}, + 127: {CoreID: 20, SocketID: 2, NUMANodeID: 2}, + 247: {CoreID: 20, SocketID: 2, NUMANodeID: 2}, + 68: {CoreID: 21, SocketID: 2, NUMANodeID: 2}, + 188: {CoreID: 21, SocketID: 2, NUMANodeID: 2}, + 128: {CoreID: 21, SocketID: 2, NUMANodeID: 2}, + 248: {CoreID: 21, SocketID: 2, NUMANodeID: 2}, + 75: {CoreID: 28, SocketID: 2, NUMANodeID: 2}, + 195: {CoreID: 28, SocketID: 2, NUMANodeID: 2}, + 135: {CoreID: 28, SocketID: 2, NUMANodeID: 2}, + 255: {CoreID: 28, SocketID: 2, NUMANodeID: 2}, + 76: {CoreID: 29, SocketID: 2, NUMANodeID: 2}, + 196: {CoreID: 29, SocketID: 2, NUMANodeID: 2}, + 136: {CoreID: 29, SocketID: 2, NUMANodeID: 2}, + 256: {CoreID: 29, SocketID: 2, NUMANodeID: 2}, + 83: {CoreID: 36, SocketID: 2, NUMANodeID: 2}, + 203: {CoreID: 36, SocketID: 2, NUMANodeID: 2}, + 143: {CoreID: 36, SocketID: 2, NUMANodeID: 2}, + 263: {CoreID: 36, SocketID: 2, NUMANodeID: 2}, + 84: {CoreID: 37, SocketID: 2, NUMANodeID: 2}, + 204: {CoreID: 37, SocketID: 2, NUMANodeID: 2}, + 144: {CoreID: 37, SocketID: 2, NUMANodeID: 2}, + 264: {CoreID: 37, SocketID: 2, NUMANodeID: 2}, + 91: {CoreID: 44, SocketID: 2, NUMANodeID: 2}, + 211: {CoreID: 44, SocketID: 2, NUMANodeID: 2}, + 151: {CoreID: 44, SocketID: 2, NUMANodeID: 2}, + 271: {CoreID: 44, SocketID: 2, NUMANodeID: 2}, + 92: {CoreID: 45, SocketID: 2, NUMANodeID: 2}, + 212: {CoreID: 45, SocketID: 2, NUMANodeID: 2}, + 152: {CoreID: 45, SocketID: 2, NUMANodeID: 2}, + 272: {CoreID: 45, SocketID: 2, NUMANodeID: 2}, + 99: {CoreID: 52, SocketID: 2, NUMANodeID: 2}, + 219: {CoreID: 52, SocketID: 2, NUMANodeID: 2}, + 159: {CoreID: 52, SocketID: 2, NUMANodeID: 2}, + 279: {CoreID: 52, SocketID: 2, NUMANodeID: 2}, + 100: {CoreID: 53, SocketID: 2, NUMANodeID: 2}, + 220: {CoreID: 53, SocketID: 2, NUMANodeID: 2}, + 160: {CoreID: 53, SocketID: 2, NUMANodeID: 2}, + 280: {CoreID: 53, SocketID: 2, NUMANodeID: 2}, + 105: {CoreID: 60, SocketID: 2, NUMANodeID: 2}, + 225: {CoreID: 60, SocketID: 2, NUMANodeID: 2}, + 165: {CoreID: 60, SocketID: 2, NUMANodeID: 2}, + 285: {CoreID: 60, SocketID: 2, NUMANodeID: 2}, + 106: {CoreID: 61, SocketID: 2, NUMANodeID: 2}, + 226: {CoreID: 61, SocketID: 2, NUMANodeID: 2}, + 166: {CoreID: 61, SocketID: 2, NUMANodeID: 2}, + 286: {CoreID: 61, SocketID: 2, NUMANodeID: 2}, + 7: {CoreID: 70, SocketID: 3, NUMANodeID: 3}, + 31: {CoreID: 70, SocketID: 3, NUMANodeID: 3}, + 19: {CoreID: 70, SocketID: 3, NUMANodeID: 3}, + 44: {CoreID: 70, SocketID: 3, NUMANodeID: 3}, + 8: {CoreID: 71, SocketID: 3, NUMANodeID: 3}, + 32: {CoreID: 71, SocketID: 3, NUMANodeID: 3}, + 20: {CoreID: 71, SocketID: 3, NUMANodeID: 3}, + 45: {CoreID: 71, SocketID: 3, NUMANodeID: 3}, + 37: {CoreID: 63, SocketID: 3, NUMANodeID: 3}, + 168: {CoreID: 63, SocketID: 3, NUMANodeID: 3}, + 108: {CoreID: 63, SocketID: 3, NUMANodeID: 3}, + 228: {CoreID: 63, SocketID: 3, NUMANodeID: 3}, + 107: {CoreID: 62, SocketID: 3, NUMANodeID: 3}, + 227: {CoreID: 62, SocketID: 3, NUMANodeID: 3}, + 167: {CoreID: 62, SocketID: 3, NUMANodeID: 3}, + 287: {CoreID: 62, SocketID: 3, NUMANodeID: 3}, + 55: {CoreID: 6, SocketID: 3, NUMANodeID: 3}, + 175: {CoreID: 6, SocketID: 3, NUMANodeID: 3}, + 115: {CoreID: 6, SocketID: 3, NUMANodeID: 3}, + 235: {CoreID: 6, SocketID: 3, NUMANodeID: 3}, + 56: {CoreID: 7, SocketID: 3, NUMANodeID: 3}, + 176: {CoreID: 7, SocketID: 3, NUMANodeID: 3}, + 116: {CoreID: 7, SocketID: 3, NUMANodeID: 3}, + 236: {CoreID: 7, SocketID: 3, NUMANodeID: 3}, + 63: {CoreID: 14, SocketID: 3, NUMANodeID: 3}, + 183: {CoreID: 14, SocketID: 3, NUMANodeID: 3}, + 123: {CoreID: 14, SocketID: 3, NUMANodeID: 3}, + 243: {CoreID: 14, SocketID: 3, NUMANodeID: 3}, + 64: {CoreID: 15, SocketID: 3, NUMANodeID: 3}, + 184: {CoreID: 15, SocketID: 3, NUMANodeID: 3}, + 124: {CoreID: 15, SocketID: 3, NUMANodeID: 3}, + 244: {CoreID: 15, SocketID: 3, NUMANodeID: 3}, + 69: {CoreID: 22, SocketID: 3, NUMANodeID: 3}, + 189: {CoreID: 22, SocketID: 3, NUMANodeID: 3}, + 129: {CoreID: 22, SocketID: 3, NUMANodeID: 3}, + 249: {CoreID: 22, SocketID: 3, NUMANodeID: 3}, + 70: {CoreID: 23, SocketID: 3, NUMANodeID: 3}, + 190: {CoreID: 23, SocketID: 3, NUMANodeID: 3}, + 130: {CoreID: 23, SocketID: 3, NUMANodeID: 3}, + 250: {CoreID: 23, SocketID: 3, NUMANodeID: 3}, + 77: {CoreID: 30, SocketID: 3, NUMANodeID: 3}, + 197: {CoreID: 30, SocketID: 3, NUMANodeID: 3}, + 137: {CoreID: 30, SocketID: 3, NUMANodeID: 3}, + 257: {CoreID: 30, SocketID: 3, NUMANodeID: 3}, + 78: {CoreID: 31, SocketID: 3, NUMANodeID: 3}, + 198: {CoreID: 31, SocketID: 3, NUMANodeID: 3}, + 138: {CoreID: 31, SocketID: 3, NUMANodeID: 3}, + 258: {CoreID: 31, SocketID: 3, NUMANodeID: 3}, + 85: {CoreID: 38, SocketID: 3, NUMANodeID: 3}, + 205: {CoreID: 38, SocketID: 3, NUMANodeID: 3}, + 145: {CoreID: 38, SocketID: 3, NUMANodeID: 3}, + 265: {CoreID: 38, SocketID: 3, NUMANodeID: 3}, + 86: {CoreID: 39, SocketID: 3, NUMANodeID: 3}, + 206: {CoreID: 39, SocketID: 3, NUMANodeID: 3}, + 146: {CoreID: 39, SocketID: 3, NUMANodeID: 3}, + 266: {CoreID: 39, SocketID: 3, NUMANodeID: 3}, + 93: {CoreID: 46, SocketID: 3, NUMANodeID: 3}, + 213: {CoreID: 46, SocketID: 3, NUMANodeID: 3}, + 153: {CoreID: 46, SocketID: 3, NUMANodeID: 3}, + 273: {CoreID: 46, SocketID: 3, NUMANodeID: 3}, + 94: {CoreID: 47, SocketID: 3, NUMANodeID: 3}, + 214: {CoreID: 47, SocketID: 3, NUMANodeID: 3}, + 154: {CoreID: 47, SocketID: 3, NUMANodeID: 3}, + 274: {CoreID: 47, SocketID: 3, NUMANodeID: 3}, + 101: {CoreID: 54, SocketID: 3, NUMANodeID: 3}, + 221: {CoreID: 54, SocketID: 3, NUMANodeID: 3}, + 161: {CoreID: 54, SocketID: 3, NUMANodeID: 3}, + 281: {CoreID: 54, SocketID: 3, NUMANodeID: 3}, + 102: {CoreID: 55, SocketID: 3, NUMANodeID: 3}, + 222: {CoreID: 55, SocketID: 3, NUMANodeID: 3}, + 162: {CoreID: 55, SocketID: 3, NUMANodeID: 3}, + 282: {CoreID: 55, SocketID: 3, NUMANodeID: 3}, }, } ) diff --git a/pkg/kubelet/cm/cpumanager/topology/BUILD b/pkg/kubelet/cm/cpumanager/topology/BUILD index 18ab41a33f4..bd5fb095200 100644 --- a/pkg/kubelet/cm/cpumanager/topology/BUILD +++ b/pkg/kubelet/cm/cpumanager/topology/BUILD @@ -33,5 +33,8 @@ go_test( name = "go_default_test", srcs = ["topology_test.go"], embed = [":go_default_library"], - deps = ["//vendor/github.com/google/cadvisor/info/v1:go_default_library"], + deps = [ + "//pkg/kubelet/cm/cpuset:go_default_library", + "//vendor/github.com/google/cadvisor/info/v1:go_default_library", + ], ) diff --git a/pkg/kubelet/cm/cpumanager/topology/topology.go b/pkg/kubelet/cm/cpumanager/topology/topology.go index f19acac5fcb..abde76931bf 100644 --- a/pkg/kubelet/cm/cpumanager/topology/topology.go +++ b/pkg/kubelet/cm/cpumanager/topology/topology.go @@ -18,13 +18,19 @@ package topology import ( "fmt" + "io/ioutil" + "strings" cadvisorapi "github.com/google/cadvisor/info/v1" "k8s.io/klog" "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" ) -// CPUDetails is a map from CPU ID to Core ID and Socket ID. +// NUMANodeInfo is a map from NUMANode ID to a list of CPU IDs associated with +// that NUMANode. +type NUMANodeInfo map[int]cpuset.CPUSet + +// CPUDetails is a map from CPU ID to Core ID, Socket ID, and NUMA ID. type CPUDetails map[int]CPUInfo // CPUTopology contains details of node cpu, where : @@ -56,10 +62,11 @@ func (topo *CPUTopology) CPUsPerSocket() int { return topo.NumCPUs / topo.NumSockets } -// CPUInfo contains the socket and core IDs associated with a CPU. +// CPUInfo contains the NUMA, socket, and core IDs associated with a CPU. type CPUInfo struct { - SocketID int - CoreID int + NUMANodeID int + SocketID int + CoreID int } // KeepOnly returns a new CPUDetails object with only the supplied cpus. @@ -73,6 +80,28 @@ func (d CPUDetails) KeepOnly(cpus cpuset.CPUSet) CPUDetails { return result } +// NUMANodes returns all of the NUMANode IDs associated with the CPUs in this +// CPUDetails. +func (d CPUDetails) NUMANodes() cpuset.CPUSet { + b := cpuset.NewBuilder() + for _, info := range d { + b.Add(info.NUMANodeID) + } + return b.Result() +} + +// NUMANodesInSocket returns all of the logical NUMANode IDs associated with +// the given Socket ID in this CPUDetails. +func (d CPUDetails) NUMANodesInSocket(id int) cpuset.CPUSet { + b := cpuset.NewBuilder() + for _, info := range d { + if info.SocketID == id { + b.Add(info.NUMANodeID) + } + } + return b.Result() +} + // Sockets returns all of the socket IDs associated with the CPUs in this // CPUDetails. func (d CPUDetails) Sockets() cpuset.CPUSet { @@ -95,6 +124,18 @@ func (d CPUDetails) CPUsInSocket(id int) cpuset.CPUSet { return b.Result() } +// SocketsInNUMANode returns all of the logical Socket IDs associated with the +// given NUMANode ID in this CPUDetails. +func (d CPUDetails) SocketsInNUMANode(id int) cpuset.CPUSet { + b := cpuset.NewBuilder() + for _, info := range d { + if info.NUMANodeID == id { + b.Add(info.SocketID) + } + } + return b.Result() +} + // Cores returns all of the core IDs associated with the CPUs in this // CPUDetails. func (d CPUDetails) Cores() cpuset.CPUSet { @@ -105,6 +146,18 @@ func (d CPUDetails) Cores() cpuset.CPUSet { return b.Result() } +// CoresInNUMANode returns all of the core IDs associated with the given +// NUMA ID in this CPUDetails. +func (d CPUDetails) CoresInNUMANode(id int) cpuset.CPUSet { + b := cpuset.NewBuilder() + for _, info := range d { + if info.NUMANodeID == id { + b.Add(info.CoreID) + } + } + return b.Result() +} + // CoresInSocket returns all of the core IDs associated with the given // socket ID in this CPUDetails. func (d CPUDetails) CoresInSocket(id int) cpuset.CPUSet { @@ -126,6 +179,18 @@ func (d CPUDetails) CPUs() cpuset.CPUSet { return b.Result() } +// CPUsInNUMANode returns all of the logical CPU IDs associated with the given +// NUMANode ID in this CPUDetails. +func (d CPUDetails) CPUsInNUMANode(id int) cpuset.CPUSet { + b := cpuset.NewBuilder() + for cpu, info := range d { + if info.NUMANodeID == id { + b.Add(cpu) + } + } + return b.Result() +} + // CPUsInCore returns all of the logical CPU IDs associated with the // given core ID in this CPUDetails. func (d CPUDetails) CPUsInCore(id int) cpuset.CPUSet { @@ -139,7 +204,7 @@ func (d CPUDetails) CPUsInCore(id int) cpuset.CPUSet { } // Discover returns CPUTopology based on cadvisor node info -func Discover(machineInfo *cadvisorapi.MachineInfo) (*CPUTopology, error) { +func Discover(machineInfo *cadvisorapi.MachineInfo, numaNodeInfo NUMANodeInfo) (*CPUTopology, error) { if machineInfo.NumCores == 0 { return nil, fmt.Errorf("could not detect number of cpus") } @@ -152,9 +217,16 @@ func Discover(machineInfo *cadvisorapi.MachineInfo) (*CPUTopology, error) { for _, core := range socket.Cores { if coreID, err := getUniqueCoreID(core.Threads); err == nil { for _, cpu := range core.Threads { + numaNodeID := 0 + for id, cset := range numaNodeInfo { + if cset.Contains(cpu) { + numaNodeID = id + } + } CPUDetails[cpu] = CPUInfo{ - CoreID: coreID, - SocketID: socket.Id, + CoreID: coreID, + SocketID: socket.Id, + NUMANodeID: numaNodeID, } } } else { @@ -194,3 +266,49 @@ func getUniqueCoreID(threads []int) (coreID int, err error) { return min, nil } + +// GetNUMANodeInfo uses sysfs to return a map of NUMANode id to the list of +// CPUs associated with that NUMANode. +// +// TODO: This is a temporary workaround until cadvisor provides this +// information directly in machineInfo. We should remove this once this +// information is available from cadvisor. +func GetNUMANodeInfo() (NUMANodeInfo, error) { + // Get the possible NUMA nodes on this machine. If reading this file + // is not possible, this is not an error. Instead, we just return a + // nil NUMANodeInfo, indicating that no NUMA information is available + // on this machine. This should implicitly be interpreted as having a + // single NUMA node with id 0 for all CPUs. + nodelist, err := ioutil.ReadFile("/sys/devices/system/node/possible") + if err != nil { + return nil, nil + } + + // Parse the nodelist into a set of Node IDs + nodes, err := cpuset.Parse(strings.TrimSpace(string(nodelist))) + if err != nil { + return nil, err + } + + info := make(NUMANodeInfo) + + // For each node... + for _, node := range nodes.ToSlice() { + // Read the 'cpulist' of the NUMA node from sysfs. + path := fmt.Sprintf("/sys/devices/system/node/node%d/cpulist", node) + cpulist, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + + // Convert the 'cpulist' into a set of CPUs. + cpus, err := cpuset.Parse(strings.TrimSpace(string(cpulist))) + if err != nil { + return nil, err + } + + info[node] = cpus + } + + return info, nil +} diff --git a/pkg/kubelet/cm/cpumanager/topology/topology_test.go b/pkg/kubelet/cm/cpumanager/topology/topology_test.go index c8441ed245d..59be5e02861 100644 --- a/pkg/kubelet/cm/cpumanager/topology/topology_test.go +++ b/pkg/kubelet/cm/cpumanager/topology/topology_test.go @@ -21,27 +21,30 @@ import ( "testing" cadvisorapi "github.com/google/cadvisor/info/v1" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" ) func Test_Discover(t *testing.T) { tests := []struct { - name string - args *cadvisorapi.MachineInfo - want *CPUTopology - wantErr bool + name string + machineInfo cadvisorapi.MachineInfo + numaNodeInfo NUMANodeInfo + want *CPUTopology + wantErr bool }{ { name: "FailNumCores", - args: &cadvisorapi.MachineInfo{ + machineInfo: cadvisorapi.MachineInfo{ NumCores: 0, }, - want: &CPUTopology{}, - wantErr: true, + numaNodeInfo: NUMANodeInfo{}, + want: &CPUTopology{}, + wantErr: true, }, { name: "OneSocketHT", - args: &cadvisorapi.MachineInfo{ + machineInfo: cadvisorapi.MachineInfo{ NumCores: 8, Topology: []cadvisorapi.Node{ {Id: 0, @@ -54,26 +57,29 @@ func Test_Discover(t *testing.T) { }, }, }, + numaNodeInfo: NUMANodeInfo{ + 0: cpuset.NewCPUSet(0, 1, 2, 3, 4, 5, 6, 7), + }, want: &CPUTopology{ NumCPUs: 8, NumSockets: 1, NumCores: 4, CPUDetails: map[int]CPUInfo{ - 0: {CoreID: 0, SocketID: 0}, - 1: {CoreID: 1, SocketID: 0}, - 2: {CoreID: 2, SocketID: 0}, - 3: {CoreID: 3, SocketID: 0}, - 4: {CoreID: 0, SocketID: 0}, - 5: {CoreID: 1, SocketID: 0}, - 6: {CoreID: 2, SocketID: 0}, - 7: {CoreID: 3, SocketID: 0}, + 0: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 1: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 2: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 3: {CoreID: 3, SocketID: 0, NUMANodeID: 0}, + 4: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 5: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 6: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 7: {CoreID: 3, SocketID: 0, NUMANodeID: 0}, }, }, wantErr: false, }, { name: "DualSocketNoHT", - args: &cadvisorapi.MachineInfo{ + machineInfo: cadvisorapi.MachineInfo{ NumCores: 4, Topology: []cadvisorapi.Node{ {Id: 0, @@ -90,22 +96,26 @@ func Test_Discover(t *testing.T) { }, }, }, + numaNodeInfo: NUMANodeInfo{ + 0: cpuset.NewCPUSet(0, 2), + 1: cpuset.NewCPUSet(1, 3), + }, want: &CPUTopology{ NumCPUs: 4, NumSockets: 2, NumCores: 4, CPUDetails: map[int]CPUInfo{ - 0: {CoreID: 0, SocketID: 0}, - 1: {CoreID: 1, SocketID: 1}, - 2: {CoreID: 2, SocketID: 0}, - 3: {CoreID: 3, SocketID: 1}, + 0: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 1: {CoreID: 1, SocketID: 1, NUMANodeID: 1}, + 2: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 3: {CoreID: 3, SocketID: 1, NUMANodeID: 1}, }, }, wantErr: false, }, { name: "DualSocketHT - non unique Core'ID's", - args: &cadvisorapi.MachineInfo{ + machineInfo: cadvisorapi.MachineInfo{ NumCores: 12, Topology: []cadvisorapi.Node{ {Id: 0, @@ -124,30 +134,34 @@ func Test_Discover(t *testing.T) { }, }, }, + numaNodeInfo: NUMANodeInfo{ + 0: cpuset.NewCPUSet(0, 6, 1, 7, 2, 8), + 1: cpuset.NewCPUSet(3, 9, 4, 10, 5, 11), + }, want: &CPUTopology{ NumCPUs: 12, NumSockets: 2, NumCores: 6, CPUDetails: map[int]CPUInfo{ - 0: {CoreID: 0, SocketID: 0}, - 1: {CoreID: 1, SocketID: 0}, - 2: {CoreID: 2, SocketID: 0}, - 3: {CoreID: 3, SocketID: 1}, - 4: {CoreID: 4, SocketID: 1}, - 5: {CoreID: 5, SocketID: 1}, - 6: {CoreID: 0, SocketID: 0}, - 7: {CoreID: 1, SocketID: 0}, - 8: {CoreID: 2, SocketID: 0}, - 9: {CoreID: 3, SocketID: 1}, - 10: {CoreID: 4, SocketID: 1}, - 11: {CoreID: 5, SocketID: 1}, + 0: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 1: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 2: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 3: {CoreID: 3, SocketID: 1, NUMANodeID: 1}, + 4: {CoreID: 4, SocketID: 1, NUMANodeID: 1}, + 5: {CoreID: 5, SocketID: 1, NUMANodeID: 1}, + 6: {CoreID: 0, SocketID: 0, NUMANodeID: 0}, + 7: {CoreID: 1, SocketID: 0, NUMANodeID: 0}, + 8: {CoreID: 2, SocketID: 0, NUMANodeID: 0}, + 9: {CoreID: 3, SocketID: 1, NUMANodeID: 1}, + 10: {CoreID: 4, SocketID: 1, NUMANodeID: 1}, + 11: {CoreID: 5, SocketID: 1, NUMANodeID: 1}, }, }, wantErr: false, }, { name: "OneSocketHT fail", - args: &cadvisorapi.MachineInfo{ + machineInfo: cadvisorapi.MachineInfo{ NumCores: 8, Topology: []cadvisorapi.Node{ {Id: 0, @@ -160,12 +174,13 @@ func Test_Discover(t *testing.T) { }, }, }, - want: &CPUTopology{}, - wantErr: true, + numaNodeInfo: NUMANodeInfo{}, + want: &CPUTopology{}, + wantErr: true, }, { name: "OneSocketHT fail", - args: &cadvisorapi.MachineInfo{ + machineInfo: cadvisorapi.MachineInfo{ NumCores: 8, Topology: []cadvisorapi.Node{ {Id: 0, @@ -178,13 +193,14 @@ func Test_Discover(t *testing.T) { }, }, }, - want: &CPUTopology{}, - wantErr: true, + numaNodeInfo: NUMANodeInfo{}, + want: &CPUTopology{}, + wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := Discover(tt.args) + got, err := Discover(&tt.machineInfo, tt.numaNodeInfo) if err != nil { if tt.wantErr { t.Logf("Discover() expected error = %v", err) diff --git a/pkg/kubelet/cm/cpumanager/topology_hints.go b/pkg/kubelet/cm/cpumanager/topology_hints.go index 7cce9e1b80a..30a983ca1d8 100644 --- a/pkg/kubelet/cm/cpumanager/topology_hints.go +++ b/pkg/kubelet/cm/cpumanager/topology_hints.go @@ -20,7 +20,6 @@ import ( "k8s.io/api/core/v1" "k8s.io/klog" - "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/socketmask" @@ -69,29 +68,21 @@ func (m *manager) GetTopologyHints(pod v1.Pod, container v1.Container) map[strin // available CPUs and the number of CPUs being requested. // // It follows the convention of marking all hints that have the same number of -// bits set as the narrowest matching SocketAffinity with 'Preferred: true', and +// bits set as the narrowest matching NUMANodeAffinity with 'Preferred: true', and // marking all others with 'Preferred: false'. func (m *manager) generateCPUTopologyHints(availableCPUs cpuset.CPUSet, request int) []topologymanager.TopologyHint { - // Discover topology in order to establish the number - // of available CPUs per socket. - topo, err := topology.Discover(m.machineInfo) - if err != nil { - klog.Warningf("[cpu manager] Error discovering topology for TopologyHint generation") - return nil - } - // Initialize minAffinity to a full affinity mask. minAffinity, _ := socketmask.NewSocketMask() minAffinity.Fill() // Iterate through all combinations of socketMasks and build hints from them. hints := []topologymanager.TopologyHint{} - socketmask.IterateSocketMasks(topo.CPUDetails.Sockets().ToSlice(), func(mask socketmask.SocketMask) { + socketmask.IterateSocketMasks(m.topology.CPUDetails.NUMANodes().ToSlice(), func(mask socketmask.SocketMask) { // Check to see if we have enough CPUs available on the current // SocketMask to satisfy the CPU request. numMatching := 0 for _, c := range availableCPUs.ToSlice() { - if mask.IsSet(topo.CPUDetails[c].SocketID) { + if mask.IsSet(m.topology.CPUDetails[c].NUMANodeID) { numMatching++ } } @@ -105,8 +96,8 @@ func (m *manager) generateCPUTopologyHints(availableCPUs cpuset.CPUSet, request // list of hints. We set all hint preferences to 'false' on the first // pass through. hints = append(hints, topologymanager.TopologyHint{ - SocketAffinity: mask, - Preferred: false, + NUMANodeAffinity: mask, + Preferred: false, }) // Update minAffinity if relevant @@ -120,7 +111,7 @@ func (m *manager) generateCPUTopologyHints(availableCPUs cpuset.CPUSet, request // to the minAffinity. Only those with an equal number of bits set will be // considered preferred. for i := range hints { - if hints[i].SocketAffinity.Count() == minAffinity.Count() { + if hints[i].NUMANodeAffinity.Count() == minAffinity.Count() { hints[i].Preferred = true } } diff --git a/pkg/kubelet/cm/cpumanager/topology_hints_test.go b/pkg/kubelet/cm/cpumanager/topology_hints_test.go index 696979374f0..cbcf40f0b06 100644 --- a/pkg/kubelet/cm/cpumanager/topology_hints_test.go +++ b/pkg/kubelet/cm/cpumanager/topology_hints_test.go @@ -23,6 +23,7 @@ import ( cadvisorapi "github.com/google/cadvisor/info/v1" v1 "k8s.io/api/core/v1" + "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/socketmask" @@ -32,7 +33,7 @@ func topologyHintLessThan(a topologymanager.TopologyHint, b topologymanager.Topo if a.Preferred != b.Preferred { return a.Preferred == true } - return a.SocketAffinity.IsNarrowerThan(b.SocketAffinity) + return a.NUMANodeAffinity.IsNarrowerThan(b.NUMANodeAffinity) } func TestGetTopologyHints(t *testing.T) { @@ -49,30 +50,41 @@ func TestGetTopologyHints(t *testing.T) { secondSocketMask, _ := socketmask.NewSocketMask(1) crossSocketMask, _ := socketmask.NewSocketMask(0, 1) - m := manager{ - policy: &staticPolicy{}, - machineInfo: &cadvisorapi.MachineInfo{ - NumCores: 12, - Topology: []cadvisorapi.Node{ - {Id: 0, - Cores: []cadvisorapi.Core{ - {Id: 0, Threads: []int{0, 6}}, - {Id: 1, Threads: []int{1, 7}}, - {Id: 2, Threads: []int{2, 8}}, - }, - }, - {Id: 1, - Cores: []cadvisorapi.Core{ - {Id: 0, Threads: []int{3, 9}}, - {Id: 1, Threads: []int{4, 10}}, - {Id: 2, Threads: []int{5, 11}}, - }, + machineInfo := cadvisorapi.MachineInfo{ + NumCores: 12, + Topology: []cadvisorapi.Node{ + {Id: 0, + Cores: []cadvisorapi.Core{ + {Id: 0, Threads: []int{0, 6}}, + {Id: 1, Threads: []int{1, 7}}, + {Id: 2, Threads: []int{2, 8}}, }, }, + {Id: 1, + Cores: []cadvisorapi.Core{ + {Id: 0, Threads: []int{3, 9}}, + {Id: 1, Threads: []int{4, 10}}, + {Id: 2, Threads: []int{5, 11}}, + }, + }, + }, + } + + numaNodeInfo := topology.NUMANodeInfo{ + 0: cpuset.NewCPUSet(0, 6, 1, 7, 2, 8), + 1: cpuset.NewCPUSet(3, 9, 4, 10, 5, 11), + } + + topology, _ := topology.Discover(&machineInfo, numaNodeInfo) + + m := manager{ + policy: &staticPolicy{ + topology: topology, }, state: &mockState{ defaultCPUSet: cpuset.NewCPUSet(2, 3, 4, 5, 6, 7, 8, 9, 10, 11), }, + topology: topology, } tcases := []struct { @@ -87,16 +99,16 @@ func TestGetTopologyHints(t *testing.T) { container: *testContainer1, expectedHints: []topologymanager.TopologyHint{ { - SocketAffinity: firstSocketMask, - Preferred: true, + NUMANodeAffinity: firstSocketMask, + Preferred: true, }, { - SocketAffinity: secondSocketMask, - Preferred: true, + NUMANodeAffinity: secondSocketMask, + Preferred: true, }, { - SocketAffinity: crossSocketMask, - Preferred: false, + NUMANodeAffinity: crossSocketMask, + Preferred: false, }, }, }, @@ -106,12 +118,12 @@ func TestGetTopologyHints(t *testing.T) { container: *testContainer2, expectedHints: []topologymanager.TopologyHint{ { - SocketAffinity: secondSocketMask, - Preferred: true, + NUMANodeAffinity: secondSocketMask, + Preferred: true, }, { - SocketAffinity: crossSocketMask, - Preferred: false, + NUMANodeAffinity: crossSocketMask, + Preferred: false, }, }, }, @@ -121,8 +133,8 @@ func TestGetTopologyHints(t *testing.T) { container: *testContainer3, expectedHints: []topologymanager.TopologyHint{ { - SocketAffinity: crossSocketMask, - Preferred: true, + NUMANodeAffinity: crossSocketMask, + Preferred: true, }, }, }, diff --git a/pkg/kubelet/cm/topologymanager/topology_manager.go b/pkg/kubelet/cm/topologymanager/topology_manager.go index 70e09627d54..af9641e7e87 100644 --- a/pkg/kubelet/cm/topologymanager/topology_manager.go +++ b/pkg/kubelet/cm/topologymanager/topology_manager.go @@ -62,10 +62,10 @@ type Store interface { GetAffinity(podUID string, containerName string) TopologyHint } -//TopologyHint is a struct containing a SocketMask for a Container +//TopologyHint is a struct containing the NUMANodeAffinity for a Container type TopologyHint struct { - SocketAffinity socketmask.SocketMask - // Preferred is set to true when the SocketMask encodes a preferred + NUMANodeAffinity socketmask.SocketMask + // Preferred is set to true when the NUMANodeAffinity encodes a preferred // allocation for the Container. It is set to false otherwise. Preferred bool } @@ -149,7 +149,7 @@ func (m *manager) iterateAllProviderTopologyHints(allProviderHints [][]TopologyH // Merge the hints from all hint providers to find the best one. func (m *manager) calculateAffinity(pod v1.Pod, container v1.Container) TopologyHint { - // Set the default hint to return from this function as an any-socket + // Set the default hint to return from this function as an any-numa // affinity with an unpreferred allocation. This will only be returned if // no better hint can be found when merging hints from each hint provider. defaultAffinity, _ := socketmask.NewSocketMask() @@ -164,9 +164,9 @@ func (m *manager) calculateAffinity(pod v1.Pod, container v1.Container) Topology // Get the TopologyHints from a provider. hints := provider.GetTopologyHints(pod, container) - // If hints is empty, insert a single, preferred any-socket hint into allProviderHints. + // If hints is nil, insert a single, preferred any-numa hint into allProviderHints. if len(hints) == 0 { - klog.Infof("[topologymanager] Hint Provider has no preference for socket affinity with any resource") + klog.Infof("[topologymanager] Hint Provider has no preference for NUMA affinity with any resource") affinity, _ := socketmask.NewSocketMask() affinity.Fill() allProviderHints = append(allProviderHints, []TopologyHint{{affinity, true}}) @@ -176,7 +176,7 @@ func (m *manager) calculateAffinity(pod v1.Pod, container v1.Container) Topology // Otherwise, accumulate the hints for each resource type into allProviderHints. for resource := range hints { if hints[resource] == nil { - klog.Infof("[topologymanager] Hint Provider has no preference for socket affinity with resource '%s'", resource) + klog.Infof("[topologymanager] Hint Provider has no preference for NUMA affinity with resource '%s'", resource) affinity, _ := socketmask.NewSocketMask() affinity.Fill() allProviderHints = append(allProviderHints, []TopologyHint{{affinity, true}}) @@ -184,7 +184,7 @@ func (m *manager) calculateAffinity(pod v1.Pod, container v1.Container) Topology } if len(hints[resource]) == 0 { - klog.Infof("[topologymanager] Hint Provider has no possible socket affinities for resource '%s'", resource) + klog.Infof("[topologymanager] Hint Provider has no possible NUMA affinities for resource '%s'", resource) affinity, _ := socketmask.NewSocketMask() affinity.Fill() allProviderHints = append(allProviderHints, []TopologyHint{{affinity, false}}) @@ -197,37 +197,37 @@ func (m *manager) calculateAffinity(pod v1.Pod, container v1.Container) Topology // Iterate over all permutations of hints in 'allProviderHints'. Merge the // hints in each permutation by taking the bitwise-and of their affinity masks. - // Return the hint with the narrowest SocketAffinity of all merged - // permutations that have at least one socket set. If no merged mask can be - // found that has at least one socket set, return the 'defaultHint'. + // Return the hint with the narrowest NUMANodeAffinity of all merged + // permutations that have at least one NUMA ID set. If no merged mask can be + // found that has at least one NUMA ID set, return the 'defaultHint'. bestHint := defaultHint m.iterateAllProviderTopologyHints(allProviderHints, func(permutation []TopologyHint) { - // Get the SocketAffinity from each hint in the permutation and see if any + // Get the NUMANodeAffinity from each hint in the permutation and see if any // of them encode unpreferred allocations. preferred := true - var socketAffinities []socketmask.SocketMask + var numaAffinities []socketmask.SocketMask for _, hint := range permutation { - // Only consider hints that have an actual SocketAffinity set. - if hint.SocketAffinity != nil { + // Only consider hints that have an actual NUMANodeAffinity set. + if hint.NUMANodeAffinity != nil { if !hint.Preferred { preferred = false } - socketAffinities = append(socketAffinities, hint.SocketAffinity) + numaAffinities = append(numaAffinities, hint.NUMANodeAffinity) } } // Merge the affinities using a bitwise-and operation. mergedAffinity, _ := socketmask.NewSocketMask() mergedAffinity.Fill() - mergedAffinity.And(socketAffinities...) + mergedAffinity.And(numaAffinities...) // Build a mergedHintfrom the merged affinity mask, indicating if an // preferred allocation was used to generate the affinity mask or not. mergedHint := TopologyHint{mergedAffinity, preferred} - // Only consider mergedHints that result in a SocketAffinity > 0 to + // Only consider mergedHints that result in a NUMANodeAffinity > 0 to // replace the current bestHint. - if mergedHint.SocketAffinity.Count() == 0 { + if mergedHint.NUMANodeAffinity.Count() == 0 { return } @@ -246,9 +246,9 @@ func (m *manager) calculateAffinity(pod v1.Pod, container v1.Container) Topology } // If mergedHint and bestHint has the same preference, only consider - // mergedHints that have a narrower SocketAffinity than the - // SocketAffinity in the current bestHint. - if !mergedHint.SocketAffinity.IsNarrowerThan(bestHint.SocketAffinity) { + // mergedHints that have a narrower NUMANodeAffinity than the + // NUMANodeAffinity in the current bestHint. + if !mergedHint.NUMANodeAffinity.IsNarrowerThan(bestHint.NUMANodeAffinity) { return } diff --git a/pkg/kubelet/cm/topologymanager/topology_manager_test.go b/pkg/kubelet/cm/topologymanager/topology_manager_test.go index 6ee19370c71..878f2c18b43 100644 --- a/pkg/kubelet/cm/topologymanager/topology_manager_test.go +++ b/pkg/kubelet/cm/topologymanager/topology_manager_test.go @@ -120,8 +120,8 @@ func TestCalculateAffinity(t *testing.T) { name: "TopologyHint not set", hp: []HintProvider{}, expected: TopologyHint{ - SocketAffinity: NewTestSocketMaskFull(), - Preferred: true, + NUMANodeAffinity: NewTestSocketMaskFull(), + Preferred: true, }, }, { @@ -132,8 +132,8 @@ func TestCalculateAffinity(t *testing.T) { }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMaskFull(), - Preferred: true, + NUMANodeAffinity: NewTestSocketMaskFull(), + Preferred: true, }, }, { @@ -146,8 +146,8 @@ func TestCalculateAffinity(t *testing.T) { }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMaskFull(), - Preferred: true, + NUMANodeAffinity: NewTestSocketMaskFull(), + Preferred: true, }, }, { @@ -160,46 +160,46 @@ func TestCalculateAffinity(t *testing.T) { }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMaskFull(), - Preferred: false, + NUMANodeAffinity: NewTestSocketMaskFull(), + Preferred: false, }, }, { - name: "Single TopologyHint with Preferred as true and SocketAffinity as nil", + name: "Single TopologyHint with Preferred as true and NUMANodeAffinity as nil", hp: []HintProvider{ &mockHintProvider{ map[string][]TopologyHint{ "resource": { { - SocketAffinity: nil, - Preferred: true, + NUMANodeAffinity: nil, + Preferred: true, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMaskFull(), - Preferred: true, + NUMANodeAffinity: NewTestSocketMaskFull(), + Preferred: true, }, }, { - name: "Single TopologyHint with Preferred as false and SocketAffinity as nil", + name: "Single TopologyHint with Preferred as false and NUMANodeAffinity as nil", hp: []HintProvider{ &mockHintProvider{ map[string][]TopologyHint{ "resource": { { - SocketAffinity: nil, - Preferred: false, + NUMANodeAffinity: nil, + Preferred: false, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMaskFull(), - Preferred: true, + NUMANodeAffinity: NewTestSocketMaskFull(), + Preferred: true, }, }, { @@ -209,8 +209,8 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, }, }, @@ -219,16 +219,16 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource2": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, }, { @@ -238,8 +238,8 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, }, @@ -248,16 +248,16 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource2": { { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, { @@ -267,8 +267,8 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, }, }, @@ -277,16 +277,16 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource2": { { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: true, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, }, { @@ -296,8 +296,8 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, }, @@ -306,16 +306,16 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource2": { { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: true, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, { @@ -325,8 +325,8 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, }, }, @@ -335,16 +335,16 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource2": { { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMaskFull(), - Preferred: false, + NUMANodeAffinity: NewTestSocketMaskFull(), + Preferred: false, }, }, { @@ -354,8 +354,8 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, }, }, @@ -364,16 +364,16 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource2": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: false, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(0), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: false, }, }, { @@ -383,8 +383,8 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, }, @@ -393,16 +393,16 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource2": { { - SocketAffinity: NewTestSocketMask(1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: false, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: false, }, }, { @@ -413,16 +413,16 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, }, { @@ -433,16 +433,16 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource": { { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, { @@ -452,12 +452,12 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, }, @@ -466,16 +466,16 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource2": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, }, { @@ -485,12 +485,12 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, }, @@ -499,16 +499,16 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource2": { { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, { @@ -518,12 +518,12 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, }, @@ -532,16 +532,16 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource2": { { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: false, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(0), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: false, }, }, { @@ -551,12 +551,12 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, }, @@ -565,20 +565,20 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource2": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: false, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, }, { @@ -588,12 +588,12 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: false, }, }, }, @@ -602,24 +602,24 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource2": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: false, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, { @@ -629,34 +629,34 @@ func TestCalculateAffinity(t *testing.T) { map[string][]TopologyHint{ "resource1": { { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: false, }, }, "resource2": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: false, }, }, }, }, }, expected: TopologyHint{ - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, }, } @@ -665,8 +665,8 @@ func TestCalculateAffinity(t *testing.T) { mngr := manager{} mngr.hintProviders = tc.hp actual := mngr.calculateAffinity(v1.Pod{}, v1.Container{}) - if !actual.SocketAffinity.IsEqual(tc.expected.SocketAffinity) { - t.Errorf("Expected SocketAffinity in result to be %v, got %v", tc.expected.SocketAffinity, actual.SocketAffinity) + if !actual.NUMANodeAffinity.IsEqual(tc.expected.NUMANodeAffinity) { + t.Errorf("Expected NUMANodeAffinity in result to be %v, got %v", tc.expected.NUMANodeAffinity, actual.NUMANodeAffinity) } if actual.Preferred != tc.expected.Preferred { t.Errorf("Expected Affinity preference in result to be %v, got %v", tc.expected.Preferred, actual.Preferred) @@ -801,12 +801,12 @@ func TestAdmit(t *testing.T) { map[string][]TopologyHint{ "resource": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: false, }, }, }, @@ -823,16 +823,16 @@ func TestAdmit(t *testing.T) { map[string][]TopologyHint{ "resource": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: false, }, }, }, @@ -849,8 +849,8 @@ func TestAdmit(t *testing.T) { map[string][]TopologyHint{ "resource": { { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: false, }, }, }, @@ -867,12 +867,12 @@ func TestAdmit(t *testing.T) { map[string][]TopologyHint{ "resource": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: false, }, }, }, @@ -889,16 +889,16 @@ func TestAdmit(t *testing.T) { map[string][]TopologyHint{ "resource": { { - SocketAffinity: NewTestSocketMask(0), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(0), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(1), - Preferred: true, + NUMANodeAffinity: NewTestSocketMask(1), + Preferred: true, }, { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: false, }, }, }, @@ -915,8 +915,8 @@ func TestAdmit(t *testing.T) { map[string][]TopologyHint{ "resource": { { - SocketAffinity: NewTestSocketMask(0, 1), - Preferred: false, + NUMANodeAffinity: NewTestSocketMask(0, 1), + Preferred: false, }, }, },