Repository navigation
feat: the Undervolt profile keeps its result only when it gains on stock (#84) - #87
Merged
Merged
Conversation
…d against stock run_stability now also averages the last half of a measurement that ran its full length (StabilityResult::counted): score, power, clocks, temperature and fan speed, when the card has run under load for minutes on either side. counted_view gives a measurement as that half. judge_against_stock decides whether the Undervolt profile keeps its result, over performance, power and thermals apart (#84): not slower than kNotSlowerScore of stock, no thermal regression, and at least one benefit. Without a valid comparison (a side that did not run its full length, or other fan control) nothing is kept. The tolerances are provisional named constants until the scatter is measured. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The measurement at stock of an Undervolt run now drives the fans with the curve the run uses (measure_stock with a curve), so the result is compared under the same fan control (#84). When its peak raises the ceiling and so moves the curve up, the card is measured at stock once more on the moved curve; that second measurement is what the result is compared with, while the first still sets the ceiling and the clock to keep. A measurement at stock that did not run its full length ends the run before the search ("not compared"). After the soak, judge_against_stock decides over the last half of both measurements. A result that is not kept is put back to stock and not saved; the RESULT line gives the reason. A kept result shows and saves those counted halves, and the window's table says that both sides ran on the app's fan curve. Not changed: the speed profiles and All in one measure stock on the driver's fans as before, and an undervolt on top of a saved tune is not judged against stock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ainst stock (#84) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…stock A card that runs hotter than 75 C at stock is measured at stock a second time, on the moved fan curve (#84): up to five minutes more than the 13 the Optimize page states. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t was judged on judge_against_stock decides on the counted half's average temperature and fan speed, but counted_view copied only score, clocks and power, and the result lines, the result screen and the saved against_stock went on showing the whole run's peak temperature and last fan reading in their place. counted_view is gone. UndervoltOutcome::before/after hold the two whole measurements as judged, and whoever shows them names each value: - counted_line (result lines): "averages of the last 150 s: score, core, power, temp, fan; whole 300 s: peak, fan at the end"; - the result screen: rows for each average, and "Peak temperature, whole run" and "Fan speed at the end" apart; - the saved against_stock (counted_against_stock): MeasuredRun gains counted_s, avg_temp_c and avg_fan_pct, written only for such a comparison, so every other profile file stays as it was; the Dashboard shows the averages next to the peak. The thresholds and the comparison are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…w the scatter is read Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the installed logon copy Three gao --undervolt runs and one from the window, each kept at 990 mV. Twice the scatter of the counted half fits every provisional tolerance. A kept result also installs the build under test as the logon copy; the procedure now says to put the installed release back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 of 5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #84. The implementation of the design in #86, for the Undervolt profile. The design was approved by the owner, including two deviations listed below. Hardware check 111 passed on the reference RTX 4070 (2026-11-14); check 112, a card that is hot at stock, has not run.
What changes
Core (
src/core/, pure logic, unit-tested):run_stabilityalso averages the last half (kCountedShare= 0.5) of a measurement that ran its full length, inStabilityResult::counted: score, power, core and memory clock, temperature and fan speed. A measurement that ended early has no counted part.counted_lineshows a measurement as it was compared: the averages, then the whole run's peak and last fan reading, each named.judge_against_stock(core/undervolt.hpp) decides whether the Undervolt profile keeps its result. It needs a valid comparison: both sides ran their full length under the same fan control. Then:kNotSlowerScore(99 %) of the stock score;kKeepCoolerC(2 C) warmer unless at leastkKeepQuieterPts(5 points) quieter, and not more than 5 points louder unless at least 2 C cooler;kKeepPowerShare(97 %) of stock's, or 2 C cooler, or 5 points quieter.Higher power alone never discards a result, and finishing the soak alone never keeps one. The tolerances are provisional named constants.
App (
src/app/):measure_stockcan drive the fans with a curve (FanDriver, handed back byFanRelease).run_undervolt, when not on top of a saved tune:not compared: the measurement at stock stopped at N C after S swhen the measurement to compare with did not run its full length;RESULT: not applied -- <reason>gives the reason with both sides' numbers.averages of the last 150 s: score= core= power= temp= fan=; whole 300 s: peak= fan at the end=;against_stock:MeasuredRungainscounted_s,avg_temp_candavg_fan_pct. They are written only for such a comparison, so every other profile file is written as before; a file without them reads as before. The Dashboard shows Temperature, average and Fans, average next to Peak temperature.Docs:
docs/development.md;docs/hardware-checks.md, marked Not run yet.Review fix (553ff50)
The verdict used the counted half's average temperature and fan speed, but the result lines, the result screen and the saved comparison showed the whole run's peak temperature and last fan reading in their place (
counted_viewcopied only score, clocks and power).counted_viewis removed, and every place now shows and keeps the averages the verdict used, with the peak and the last reading named apart (see above). The thresholds and the comparison are unchanged.Deviations from the design, approved by the owner
gao --undervolt --on-overclock, the undervolt step of All in one) is not judged against stock. Its clock is lower than the overclock's on purpose, so "not slower than the reference" would discard it every time.Tests
cmake --workflow --preset ci(Release,/W4 /WX): no warnings.core_tests: 514 test cases, 11794 assertions, all passed (was 501). New tests cover:counted_line;against_stockfields: written only with averages, read back, and ignored unless all three are there;judge_against_stockwith the RTX 4070 and GTX 1080 Ti numbers, every rule at its boundary, a missing reading, other fan control, and a soak without a counted part.app_tests: 55 test cases, 320 assertions, all passed (was 52). New tests cover:counted_against_stock) keeping the judged averages through a profile-file round-trip.Hardware check 111: passed on the reference RTX 4070 (2026-11-14)
Build f2b235e, driver 617.42, fan curve 50 C 52 %, 70 C 52 %, 75 C 100 %.
No second measurement at stock, as expected: the card peaked at 71 to 72 C on the curve.
The scatter, twice the range over the three command-line runs (one tune, so it is measurement noise):
Every tolerance holds. The values stay as they are. Power, temperature and fan are whole numbers, so a range of 1 is the smallest step; the temperature tolerance sits at twice that step.
The window and the Dashboard showed the judged averages with the right headers, rows and notes. The window run scored about 0.3 % lower on both sides; it is left out of the scatter.
Not seen on hardware: a result that is discarded, and
not compared:. These are covered by unit tests only.Found during the check, not caused by this PR: a kept result also installs the build under test as the copy the logon task starts (
update_logon_copy). This is existing behaviour. The procedure inAGENTS.mdand checks 111 and 112 now says to put the installed release back afterwards; that was done here.Hardware check 112: not run
It needs a tester with a GTX 1080 Ti or RTX 3080 Ti that runs hot at stock. A local test build, version
0.4.10-check112, has been prepared with instructions. It is not published.Not to be merged before the owner's review.
🤖 Generated with Claude Code