Fix `_burn` bigint blowup, ctx-mgr `_read_mhz`

Both `_burn()` impls (the `cpu-perf-check` script + the
`_measure_sustained_headroom()` probe in `tests.conftest`) grew `x`
~x**2 per iter, so the loop quickly went bigint alloc/mul-bound — a
noisy CPU load + needless memory across N procs. Mask each step to
64-bit for a steady, fixed-width ALU burn (still pegs every core,
which is all the freq probe needs).

Also, `_read_mhz()` opened the sysfs freq files without a ctx-mgr;
`with open(...)` so the FD closes deterministically (matches the
script's own `_read()`).

Review: PR #468 (Copilot)
https://github.com/goodboy/tractor/pull/468

(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
test_cpu_throttling
Gud Boi 2026-06-29 17:00:53 -04:00
parent 707caf63d1
commit 5b1a9edeb3
2 changed files with 12 additions and 3 deletions

View File

@ -77,9 +77,13 @@ def _pkg_max_mhz() -> int:
def _burn(stop: float) -> None: def _burn(stop: float) -> None:
# fixed-width (64-bit-masked) arithmetic keeps this a steady
# ALU load; an unmasked `x` grows ~x**2/iter into a huge bigint,
# degenerating into noisy alloc/mul-bound work (and needless
# memory) across N procs.
x: int = 1 x: int = 1
while time.perf_counter() < stop: while time.perf_counter() < stop:
x += x * x ^ 0x5 x = (x + (x * x ^ 0x5)) & 0xFFFF_FFFF_FFFF_FFFF
def main( def main(

View File

@ -171,7 +171,8 @@ def _measure_sustained_headroom(
def _read_mhz(path: str) -> int|None: def _read_mhz(path: str) -> int|None:
try: try:
return int(open(path).read()) // 1000 with open(path) as f:
return int(f.read()) // 1000
except OSError: except OSError:
return None return None
@ -187,9 +188,13 @@ def _measure_sustained_headroom(
return 1. return 1.
def _burn(stop: float) -> None: def _burn(stop: float) -> None:
# fixed-width (64-bit-masked) arithmetic keeps this a
# steady ALU load; an unmasked `x` grows ~x**2/iter into
# a huge bigint, degenerating into noisy alloc/mul-bound
# work (and needless memory) across N procs.
x: int = 1 x: int = 1
while time.perf_counter() < stop: while time.perf_counter() < stop:
x += x * x ^ 0x5 x = (x + (x * x ^ 0x5)) & 0xFFFF_FFFF_FFFF_FFFF
# explicit `fork` ctx so we're immune to whatever global # explicit `fork` ctx so we're immune to whatever global
# mp start-method tractor/the suite may have set (`spawn` # mp start-method tractor/the suite may have set (`spawn`