mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-25 11:12:13 +08:00
Fix vision CPU throttling with offline cores
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import lru_cache
|
||||
import math
|
||||
from pathlib import Path
|
||||
import time
|
||||
|
||||
|
||||
@@ -11,9 +13,34 @@ DEVICE_BUSY_HOT_CORE_COUNT = 4
|
||||
_throttle_state: dict[str, dict[str, float]] = {}
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def _online_cpu_count() -> int | None:
|
||||
try:
|
||||
spec = Path("/sys/devices/system/cpu/online").read_text(encoding="utf-8").strip()
|
||||
count = 0
|
||||
for group in spec.split(","):
|
||||
bounds = group.split("-", maxsplit=1)
|
||||
first = int(bounds[0])
|
||||
last = int(bounds[-1])
|
||||
if last < first:
|
||||
return None
|
||||
count += last - first + 1
|
||||
return count or None
|
||||
except (OSError, ValueError):
|
||||
return None
|
||||
|
||||
|
||||
def _online_cpu_usage(cpu_usage) -> list[float]:
|
||||
usage = [float(value) for value in cpu_usage]
|
||||
online_count = _online_cpu_count()
|
||||
if online_count is not None and online_count < len(usage):
|
||||
return usage[:online_count]
|
||||
return usage
|
||||
|
||||
|
||||
def device_cpu_throttle_factor(cpu_usage, name="vision"):
|
||||
"""Return a process-local, low-pass-filtered CPU throttle factor."""
|
||||
usage = list(cpu_usage)
|
||||
usage = _online_cpu_usage(cpu_usage)
|
||||
if not usage:
|
||||
return 1.0
|
||||
|
||||
@@ -34,7 +61,7 @@ def device_cpu_throttle_factor(cpu_usage, name="vision"):
|
||||
state["factor"] = min(max(target_factor * alpha + state["factor"] * (1.0 - alpha), 1.0), 4.0)
|
||||
|
||||
if state["factor"] >= state["last_logged_factor"] + 0.6:
|
||||
print(f"[{name}] CPU throttle factor={state['factor']:.1f}x (avg={average:.0f}%, hot={hot_cores})")
|
||||
print(f"[{name}] CPU throttle factor={state['factor']:.1f}x (avg={average:.0f}%, hot={hot_cores}/{len(usage)})")
|
||||
state["last_logged_factor"] = state["factor"]
|
||||
elif state["factor"] <= 1.05 and state["last_logged_factor"] > 1.05:
|
||||
print(f"[{name}] CPU recovered")
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import pytest
|
||||
|
||||
from openpilot.starpilot.common import cpu_throttle
|
||||
|
||||
|
||||
def test_offline_cpu_placeholders_do_not_hide_sustained_load(monkeypatch):
|
||||
monkeypatch.setattr(cpu_throttle, "_online_cpu_count", lambda: 4)
|
||||
|
||||
usage = cpu_throttle._online_cpu_usage([80, 80, 80, 80, 0, 0, 0, 0])
|
||||
average = sum(usage) / len(usage)
|
||||
|
||||
assert usage == [80.0, 80.0, 80.0, 80.0]
|
||||
assert cpu_throttle._compute_throttle_factor(average, 0) == pytest.approx(1.75)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("online_spec", "expected"), (
|
||||
("0-3", 4),
|
||||
("0-3,6-7", 6),
|
||||
))
|
||||
def test_online_cpu_count_parser(monkeypatch, tmp_path, online_spec, expected):
|
||||
online_path = tmp_path / "online"
|
||||
online_path.write_text(online_spec, encoding="utf-8")
|
||||
monkeypatch.setattr(cpu_throttle, "Path", lambda _: online_path)
|
||||
cpu_throttle._online_cpu_count.cache_clear()
|
||||
|
||||
assert cpu_throttle._online_cpu_count() == expected
|
||||
Reference in New Issue
Block a user