Skip to content

BalaclavaAM/undervolt-autotuner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

undervolt-autotuner

Automatically finds the useful Curve Optimizer (undervolt) limit of an AMD Ryzen laptop by measuring real performance — not just waiting for crashes.

Built for and tested on the ASUS ROG Zephyrus G14 2025 (Ryzen AI 9 HX 370 "Strix Point"). The tool hard-gates on the Strix Point family; porting to other Ryzen families means extending the SMU command table.

CLI output is currently in Spanish. Code and identifiers are in English.

Why "useful limit" instead of "stable limit"

Recent Ryzen chips protect themselves from undervolt-induced crashes with clock stretching: instead of crashing, the silicon silently reduces effective frequency. The consequence: "it doesn't crash at -80mV" tells you nothing — your chip may well be slower at -80 than at -20.

So this tool defines the limit by diminishing returns on measured performance: it benchmarks every offset under sustained thermally-limited load and stops where the gains flatten out (or where computation errors / WHEA events appear).

Real result from the reference machine (G14 2025, HX 370)

Offset Median Pi 2.5b Cumulative gain vs stock
0 84.04 s
-5 81.00 s +3.6%
-10 80.80 s +3.9%
-15 79.08 s +5.9%
-20 76.94 s +8.4%
-25 FAILED benchmark died mid-run

At -25 the chip fell into severe protective throttling (35 W / ~3.6 GHz for a minute) and the next run died without output — no crash, no BSOD. A crash-based tuner would have kept going deeper.

How it works

  • Control layer — talks to the Ryzen SMU through the signed PawnIO driver (Secure Boot friendly; no WinRing0). SMU mailbox code adapted from G-Helper (GPL-3.0). Offsets are encoded as 20-bit two's complement (RyzenAdj --set-coall convention) and sent via MP1 command 0x4C (Strix Point). Offsets are volatile by design: any reboot returns to stock — that's the safety net.
  • Measurement layery-cruncher Pi benchmark as a deterministic workload: computation time is the metric and y-cruncher validates its own math (a spot-check failure = unstable offset, no crash needed). Telemetry via LibreHardwareMonitorLib; WHEA corrected-error monitoring (event ID 19) via the Windows event log.
  • Orchestration layer — state machine persisted to state.json before each offset is applied; a Scheduled Task finalizes the verdict after a mid-test reboot (pattern borrowed from CoreCycler). Thermal guard (≥97 °C sustained 10 s, or ≥100 °C instant) aborts any run. Curve Optimizer is restored to 0 on every exit path.

Measurement protocol (calibrated on real hardware)

The benchmark is thermally limited, so chassis temperature is a confounder:

  • Adaptive soak: the first step runs up to 4 discarded warmups until two consecutive times differ <1% (a cold chassis inflates the baseline ~3%, masking the undervolt's gain).
  • Median of 3 runs per offset (measured run-to-run CV: ~2.3% when hot).
  • Plateau needs confirmation: the sweep stops only after 2 consecutive steps without a ≥2% improvement over the best offset so far.
  • Per-core validation: the winning offset is stress-validated core-by-core (1 thread pinned per physical core, where boost is highest and undervolts fail first), with per-run spot checks and continuous WHEA monitoring.

Commands

autotuner probe                      Read-only SMU sanity check (PawnIO + mailbox)
autotuner set --offset <N>           Apply Curve Optimizer all-core (N in [-40, 0], volatile)
autotuner reset                      Restore Curve Optimizer to 0
autotuner bench [--size <S>]         One instrumented benchmark (telemetry + WHEA)
autotuner sweep [--floor -40]        Full sweep 0 → floor with plateau detection
autotuner validate --offset <N>      Long per-core validation of a candidate offset
autotuner resume                     Post-reboot recovery (invoked by the Scheduled Task)

Typical session:

# From an elevated terminal, on AC power:
autotuner probe          # verify the SMU chain
autotuner sweep          # ~35-45 min: finds the useful limit
autotuner validate --offset <winner> --minutes 60   # overnight-friendly

Then persist the validated value with G-Helper (Fans + Power → Advanced → CPU undervolt), which re-applies it on every boot. This tool deliberately does not persist anything.

Requirements

  • ASUS Zephyrus G14 2025 / Ryzen AI 9 HX 370 (other Strix Point machines will probably work; everything else is rejected)
  • Windows 11, elevated terminal, AC power
  • PawnIO driver installed
  • .NET 8 SDK
  • y-cruncher binaries in tools/y-cruncher/ — copy them from CoreCycler's test_programs/y-cruncher/ (not redistributed here)
  • Heads-up: Windows Smart App Control blocks locally-built unsigned binaries; developing/running this requires it off

Safety rules (non-negotiable, enforced in code)

  1. Preflight: elevation, AC power, PawnIO reachable, CPU allowlist.
  2. Thermal guard: abort at ≥97 °C sustained (10 s) or ≥100 °C (Tjmax) instant.
  3. Hard offset floor: -40. The tool never goes below it.
  4. Curve Optimizer restored to 0 on exit — normal, Ctrl+C, exception, or reboot (volatility + recovery task).
  5. Every run logs to logs/ — after a crash, the log is the evidence.

Use at your own risk. Undervolting is out-of-spec operation. The reboot-resets-everything design keeps the blast radius small, but you are the one pressing enter.

Credits

  • G-Helper (seerge) — PawnIO wrapper and Ryzen SMU mailbox code, adapted under GPL-3.0
  • CoreCycler (sp00n) — per-core cycling and crash-recovery patterns, y-cruncher packaging
  • y-cruncher (Alexander J. Yee) — the benchmark/validator workload
  • RyzenAdj — SMU command documentation
  • LibreHardwareMonitor — telemetry

License

GPL-3.0 — inherited from the adapted G-Helper code, and gladly so.

About

Auto-tuner that finds your Ryzen laptop's useful undervolt limit via benchmark sweeps, WHEA monitoring, and crash-safe state recovery

Resources

License

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages