diff --git a/html/input.php b/html/input.php index ad3386e..c475283 100644 --- a/html/input.php +++ b/html/input.php @@ -27,20 +27,18 @@ function saveCoreState(array $state): void } /* --------------------------------------------------------- - NUMA + SMT TOPOLOGY (SOURCE OF TRUTH) + NUMA TOPOLOGY --------------------------------------------------------- */ function getNumaTopology(): array { $nodes = []; - /* discover NUMA nodes */ foreach (glob('/sys/devices/system/node/node*') as $nodePath) { $node = (int)str_replace('node', '', basename($nodePath)); $nodes[$node] = []; } - /* map cpu -> node -> core_id */ foreach (glob('/sys/devices/system/cpu/cpu[0-9]*') as $cpuPath) { $cpu = (int)str_replace('cpu', '', basename($cpuPath)); $topo = "$cpuPath/topology"; @@ -64,12 +62,11 @@ function getNumaTopology(): array $nodes[$node][$coreId][] = $cpu; } - /* normalize ordering */ ksort($nodes); foreach ($nodes as &$cores) { ksort($cores); foreach ($cores as &$threads) { - sort($threads); // primary thread first + sort($threads); } } @@ -77,37 +74,50 @@ function getNumaTopology(): array } /* --------------------------------------------------------- - BUILD GLOBAL ROUND-ROBIN PLAN - EVEN CPUs FIRST → ODD CPUs + NUMA-AWARE ROUND-ROBIN PLAN --------------------------------------------------------- */ function buildAllocationPlan(array $nodes): array { - $even = []; - $odd = []; + $perNode = []; + /* build per-node even → odd cpu lists */ foreach ($nodes as $node => $cores) { - foreach ($cores as $coreId => $threads) { - foreach ($threads as $cpu) { - $entry = [ - "node" => $node, - "cpu" => $cpu - ]; + $even = []; + $odd = []; + foreach ($cores as $threads) { + foreach ($threads as $cpu) { if (($cpu % 2) === 0) { - $even[] = $entry; + $even[] = $cpu; } else { - $odd[] = $entry; + $odd[] = $cpu; } } } + + sort($even); + sort($odd); + + $perNode[$node] = array_merge($even, $odd); + } + + /* interleave nodes (true NUMA rotation) */ + $plan = []; + $max = max(array_map('count', $perNode)); + + for ($i = 0; $i < $max; $i++) { + foreach ($perNode as $node => $cpus) { + if (isset($cpus[$i])) { + $plan[] = [ + "node" => $node, + "cpu" => $cpus[$i] + ]; + } + } } - /* deterministic ordering */ - usort($even, fn($a, $b) => $a["cpu"] <=> $b["cpu"]); - usort($odd, fn($a, $b) => $a["cpu"] <=> $b["cpu"]); - - return array_merge($even, $odd); + return $plan; } /* --------------------------------------------------------- @@ -141,11 +151,8 @@ function allocateCore(int $serviceId): array function freeCore(int $serviceId): void { $state = loadCoreState(); - - if (isset($state["allocations"][$serviceId])) { - unset($state["allocations"][$serviceId]); - saveCoreState($state); - } + unset($state["allocations"][$serviceId]); + saveCoreState($state); } function getServiceCore(int $serviceId): ?array @@ -270,9 +277,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST" && $_POST["action"] === "edit") { ]; $new = $row; - $alloc = getServiceCore($id); + $alloc = getServiceCore($new["id"]); if ($alloc === null) { - $alloc = allocateCore($id); + $alloc = allocateCore($new["id"]); } $core = (int)$alloc["cpu"];