update
This commit is contained in:
parent
cf36fbfe71
commit
b88c2876b7
|
|
@ -7,6 +7,22 @@ if (!file_exists($coreFile)) {
|
||||||
file_put_contents($coreFile, json_encode([]));
|
file_put_contents($coreFile, json_encode([]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNumaTopology(): array
|
||||||
|
{
|
||||||
|
$out = shell_exec("numactl --hardware");
|
||||||
|
$nodes = [];
|
||||||
|
|
||||||
|
foreach (explode("\n", $out) as $line) {
|
||||||
|
if (preg_match('/node (\d+) cpus:\s+(.*)/', $line, $m)) {
|
||||||
|
$node = (int)$m[1];
|
||||||
|
$cpus = array_map('intval', preg_split('/\s+/', trim($m[2])));
|
||||||
|
$nodes[$node] = $cpus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $nodes;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get total CPU cores */
|
/* Get total CPU cores */
|
||||||
function getTotalCores(): int
|
function getTotalCores(): int
|
||||||
{
|
{
|
||||||
|
|
@ -14,69 +30,66 @@ function getTotalCores(): int
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate next free core */
|
/* Allocate next free core */
|
||||||
function allocateCore(int $serviceId): int
|
function allocateCore(int $serviceId): array
|
||||||
{
|
{
|
||||||
global $coreFile;
|
global $coreFile;
|
||||||
|
|
||||||
$map = json_decode(file_get_contents($coreFile), true) ?: [];
|
$map = json_decode(file_get_contents($coreFile), true) ?: [];
|
||||||
$total = getTotalCores();
|
$usedCores = array_column($map, 'cpu');
|
||||||
|
|
||||||
if ($total < 2) {
|
$nodes = getNumaTopology();
|
||||||
$map[$serviceId] = 0;
|
$nodeIds = array_keys($nodes);
|
||||||
|
$nodeCount = count($nodeIds);
|
||||||
|
|
||||||
|
/* Alternate NUMA nodes */
|
||||||
|
$index = count($map);
|
||||||
|
$node = $nodeIds[$index % $nodeCount];
|
||||||
|
|
||||||
|
foreach ($nodes[$node] as $cpu) {
|
||||||
|
if (!in_array($cpu, $usedCores, true)) {
|
||||||
|
$map[$serviceId] = [
|
||||||
|
"node" => $node,
|
||||||
|
"cpu" => $cpu
|
||||||
|
];
|
||||||
file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT));
|
file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT));
|
||||||
return 0;
|
return $map[$serviceId];
|
||||||
}
|
|
||||||
|
|
||||||
$half = intdiv($total, 2);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Build desired order:
|
|
||||||
0, half, 1, half+1, 2, half+2, ...
|
|
||||||
*/
|
|
||||||
$order = [];
|
|
||||||
for ($i = 0; $i < $half; $i++) {
|
|
||||||
$order[] = $i;
|
|
||||||
if (($i + $half) < $total) {
|
|
||||||
$order[] = $i + $half;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$used = array_values($map);
|
/* Fallback: any free CPU */
|
||||||
|
foreach ($nodes as $n => $cpus) {
|
||||||
foreach ($order as $core) {
|
foreach ($cpus as $cpu) {
|
||||||
if (!in_array($core, $used, true)) {
|
if (!in_array($cpu, $usedCores, true)) {
|
||||||
$map[$serviceId] = $core;
|
$map[$serviceId] = ["node" => $n, "cpu" => $cpu];
|
||||||
file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT));
|
file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT));
|
||||||
return $core;
|
return $map[$serviceId];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fallback (should never hit unless fully occupied) */
|
/* Absolute fallback */
|
||||||
$core = $order[count($map) % count($order)];
|
return ["node" => 0, "cpu" => 0];
|
||||||
$map[$serviceId] = $core;
|
|
||||||
file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT));
|
|
||||||
return $core;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Free core on delete */
|
/* Free core on delete */
|
||||||
function freeCore(int $serviceId): void
|
function freeCore(int $serviceId): void
|
||||||
{
|
{
|
||||||
global $coreFile;
|
global $coreFile;
|
||||||
|
$map = json_decode(file_get_contents($coreFile), true) ?: [];
|
||||||
|
|
||||||
$cores = json_decode(file_get_contents($coreFile), true);
|
if (isset($map[$serviceId])) {
|
||||||
if (isset($cores[$serviceId])) {
|
unset($map[$serviceId]);
|
||||||
unset($cores[$serviceId]);
|
file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT));
|
||||||
file_put_contents($coreFile, json_encode($cores, JSON_PRETTY_PRINT));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get assigned core */
|
/* Get assigned core */
|
||||||
function getServiceCore(int $serviceId): ?int
|
function getServiceCore(int $serviceId): ?array
|
||||||
{
|
{
|
||||||
global $coreFile;
|
global $coreFile;
|
||||||
|
$map = json_decode(file_get_contents($coreFile), true) ?: [];
|
||||||
$cores = json_decode(file_get_contents($coreFile), true);
|
return $map[$serviceId] ?? null;
|
||||||
return $cores[$serviceId] ?? null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$jsonFile = __DIR__ . "/input.json";
|
$jsonFile = __DIR__ . "/input.json";
|
||||||
|
|
@ -111,9 +124,14 @@ if ($_SERVER["REQUEST_METHOD"] === "POST" && $_POST["action"] === "add") {
|
||||||
|
|
||||||
$data[] = $new;
|
$data[] = $new;
|
||||||
file_put_contents($jsonFile, json_encode($data, JSON_PRETTY_PRINT));
|
file_put_contents($jsonFile, json_encode($data, JSON_PRETTY_PRINT));
|
||||||
$core = allocateCore($new["id"]);
|
|
||||||
|
|
||||||
$ffmpeg = 'taskset -c ' . $core . ' ffmpeg -hide_banner -loglevel info \
|
$alloc = allocateCore($id);
|
||||||
|
$node = $alloc["node"];
|
||||||
|
$core = $alloc["cpu"];
|
||||||
|
|
||||||
|
$ffmpeg = 'numactl --cpunodebind=' . $node .
|
||||||
|
' --membind=' . $node .
|
||||||
|
' taskset -c ' . $core . ' ffmpeg -hide_banner -loglevel info \
|
||||||
-thread_queue_size 65536 \
|
-thread_queue_size 65536 \
|
||||||
-fflags +genpts+discardcorrupt+nobuffer \
|
-fflags +genpts+discardcorrupt+nobuffer \
|
||||||
-readrate 1.0 \
|
-readrate 1.0 \
|
||||||
|
|
@ -330,7 +348,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST" && $_POST["action"] === "restart") {
|
||||||
|
|
||||||
<div class="containerindex">
|
<div class="containerindex">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="card wide">
|
<div class="card">
|
||||||
|
|
||||||
<h2>Service List</h2>
|
<h2>Service List</h2>
|
||||||
<button onclick="openAddPopup()">Add Service</button>
|
<button onclick="openAddPopup()">Add Service</button>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue