Repository navigation
All in one: overclock, undervolt on top, fan tune and a final test in one click - #21
Merged
Merged
Conversation
`gao --undervolt` saves what it found, like `gao --optimize` does: a profile with the new preset `undervolt`, stock clocks and power, and the flat top (the anchor's voltage, the clock, and the raise it was tested with). It replaces a saved overclock, because a core offset and a flat top are one table on the card. A profile whose undervolt cannot be read whole is no profile. Applying it at logon and watching it follow in the next commits. Hardware check 66 on the reference RTX 4070. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
apply_profile writes the profile's flat top on the curve point with the saved voltage, after power and memory. It is refused, with the card at stock, when the curve has no such point or when the point would have to be raised further than the undervolt was tested with plus what the built-in curve moves with temperature. A core offset next to an undervolt is refused before any write. Every apply removes a flat top that is on the card first: an offset write that asks for what the driver already reports changes nothing. `gao --status` says whether the undervolt is applied, from the curve: the offset read-out reports core +0 with a flat top on the card. Hardware check 67 on the reference RTX 4070. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tray app's watchdog judges a profile with an undervolt by the curve (a flat top at the saved voltage, stock, or something else), not by the core offset, which reads +0 under a flat top. An undervolt that was reset is re-applied; another program's offsets are left alone. Two changes for every tune, overclock or undervolt: - A driver reset that leaves the tune applied now counts like one that undid it. The tray app already sees driver resets (its display device is removed) and passes them on; a search's own resets are not counted. - Giving up (a fourth reset within an hour) sets the card to stock instead of leaving whatever the driver kept, and the tune is no longer watched. `gao --undervolt` no longer tells a running tray app to stand down: the tuning lock holds it off during the run, as for `gao --optimize`, and afterwards it finds the profile the run saved. Hardware check 68 on the reference RTX 4070: re-applied three times, given up at stock the fourth, a foreign offset left alone, and a forced driver reset (which removes a flat top) survived and re-applied. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A fifth card, Undervolt, under the four clock profiles on the dashboard and on the Optimize page. With it selected the button reads "Undervolt GPU" and starts the undervolt search on the worker thread; the run screen lists its probes, the result screen shows the clock, the voltage it now runs at next to the card's own, and a before/after table. A run that ends saved leaves the watchdog on, like an optimize run. The dashboard judges "applied now" by the curve when an undervolt is saved, and shows it on a row of its own. Hardware check 69 on the reference RTX 4070: the run started from the window, saved, and was re-applied by the watchdog. The check also showed that the saving shrinks once the card is warm (the built-in curve moves under the written offsets) and that the result table compares a 30 s run with a 300 s one; both are recorded there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ran and at what fan speed During a run from the window the run screen draws the card's voltage/frequency curve as the run writes it, read back once a second, over the card's own curve, with a dot where the card runs now. An undervolt shows as a flat top that starts one point further left with each candidate; an overclock lifts the whole line. The result screen shows the curve as the run left it. The before/after table compared a 30 s run at stock with the 300 s soak without saying so. It now names both durations in its headers, shows the fan speed each run ended on next to its peak temperature (StabilityResult end_fan_pct; the command line prints it too), and says that the short stock run was not heated through, so that only score, clock and power compare directly. README and design notes: the Undervolt profile, the curve picture, the watchdog's new rule, and what the hardware checks of this branch found: the power saved depends on the temperature the card settles at (25, 22, 20 and 12 % in four runs), because the built-in curve moves under the written offsets. Hardware check 70 on the reference RTX 4070. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts long measurements down The stock measurement of the undervolt run lasted 30 s and the soak of its result 300 s. A card is not heated through after half a minute, so the "before" temperature and fan speed read low and a result looked no cooler than stock. The stock measurement now lasts as long as the soak. On the reference RTX 4070 that is 67 C at 72 % fan and 196 W at stock against 61 C at 66 % fan and 166 W with the undervolt, where the short stock run had read 59 to 61 C. The run takes four and a half minutes longer. The search announces every measurement of 30 s or more (stock, confirm, soak) and the run screen shows what is being measured, the time left and a bar. The table's headers follow the real durations, so its note about a short stock run no longer appears for an undervolt. The optimize run of the clock profiles is unchanged: its 30 s stock score is the reference of the power search. Hardware check 71 on the reference RTX 4070. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ays on the anchor's voltage A top written exactly flat does not stay flat: the card's built-in curve moves with temperature, each point by its own step. On the reference RTX 4070 the same offsets ran in two ways once the card was warm: on the anchor's voltage one clock step lower (154 W), or on a higher voltage holding the clock (163 to 168 W). apply_flat_top now stores the points above the anchor 45 MHz below it (kVfTailDropKhz), which makes the anchor the highest point whatever the temperature does. The card reports for every point the most that it or any point below it runs, so those points keep reading the anchor's frequency: the top is written flat and read back first, as before, and then lowered in one write that is checked by the offsets. A card that does not store them is refused, at stock. `gao --curve-flatten <mV> <MHz> 0` still writes the exactly flat top. Hardware check 72 on the reference RTX 4070: never above 156 W with the lowered points in five stress runs between 50 and 60 C, all stable; the undervolt run's soak 155 W against 195 W at stock (20.5 % less) at 99.6 % of the score, where the flat top had given 166 W (15.3 % less) at 99.8 %. At the same clock the two shapes draw the same; the lowered points keep the card from buying the last 15 MHz with 12 W. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A second result section next to the overclock one: 195 W at stock and 155 W with the undervolt (20.5 % less) at 99.6 % of the stress-test score, 59 C instead of 67 C and 64 % fan speed instead of 72 %, both sides five minutes of load on a card that is heated through (hardware check 72). The sentence in the Profiles section that carried these numbers now only says what the lowered points above the anchor are for. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tead of a radio button The fan icon was a glyph that is a ring of dots: the icon fonts of Windows have no fan. It is now drawn (a casing ring, a hub and three swept blades) on the Fan speed tile and in the navigation. The profile cards showed a radio button, an icon and the title in a row. The radio button said what the card's border and colour already say, and the icons sat unevenly next to the titles because the font's glyphs differ in width and in where they sit in their cell. Each card now has its icon in a square badge, centred by the glyph's own outline, with the title level with it; the selected card's badge is filled. README: the undervolt result section is titled "almost the same speed" (the measurement is 99.6 % of the score), and the dashboard picture is new. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tile centred a block of 2.45 em, but the label and the value were laid out with the style's own line spacing between them, so the block was taller than that and the value hung at the bottom of the tile, away from the icon and the label. They are now spaced as the block assumes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A core offset and the voltage/frequency curve are one table on the card, so an undervolt on top of an overclock is one shape: the core offset on every point below the anchor, the anchor raised further, the points above it lower. apply_flat_top takes that base offset, levels the curve to it first and keeps it on the points below the anchor; curve_state knows a flat top over an offset from the bare offset and from stock. apply_profile no longer refuses a profile with both. It checks the flat top against the built-in curve before any clock is written (the raise counts from there, offset included), sets power, core and memory, and writes the flat top over the core offset. `gao --curve-flatten <mV> <MHz> [<drop> [<core>]]` writes it by hand. Hardware check 73 on the reference RTX 4070: core +135 alone ran 2895 MHz at 199 W and 67 C; with a flat top over it at 1015 mV, 2880 MHz at 172 W and 62 C, stable, and the driver still reports core +135. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
find_undervolt takes the overclock it runs on (power limit, core and memory offsets): it sets it after every reset to stock, keeps the clock the card runs with it, writes its flat tops over the core offset and counts every raise over the built-in curve, offset included: for the journal, for the margin and for the result. `gao --undervolt --on-overclock` runs it on the saved tune and saves the undervolt into that profile. Hardware check 74 on the reference RTX 4070: it works, and adds little. Core +135 at 105 % ran 2906 MHz on 201 W; the undervolt on top of it, 2895 MHz on 196 W. With the margin of 70 % on the raise that held (225 MHz over the built-in curve) 150 MHz is left, and the overclock is 135 of it: an overclock already is an undervolt at every frequency. The two are ends of one line, not gains that add up. curve_state: a flat top whose anchor needed no raise of its own (the offset curve already ran the target there; only the points above are stored lower) is a flat top. The run above ended on one, and `gao --status` called it "other offsets". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y measuring tune_fan sets the fans by hand under a running load, waits for the temperature to settle, and goes five percent lower until the card settles above the target (the profile's limit minus 5 C) or the fans' minimum is reached; a start that is too quiet goes up instead. The result is the lowest speed that held and a fan curve through that point. A load that stops computing right ends the tune, and every way out that is not a success hands the fans back to the driver. Core and unit tests only; nothing calls it yet. A probe result now carries the temperature at its last sample. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…and a final test in one run
`run_all_in_one`, `gao --optimize all` and the card "All in one" in the
window (the default now) run, under one tuning lock:
1. five minutes at stock, to compare with;
2. the overclock of Best of my GPU;
3. an undervolt on top of it, at a clock half-way between what the card
ran at stock and what it runs with the overclock;
4. the fan tune: the quietest speed that holds the temperature target;
5. five minutes with everything applied, fans on the tuned curve.
The result screen shows the card at stock next to the card now. A step that
fails keeps what the steps before it found; a stop request ends at stock.
The half-way clock is a choice. An overclock and an undervolt are two ends
of one line (hardware check 74), and the middle is where the result beats
stock on both counts. find_undervolt takes that clock from its caller and
then also accepts the overclock's curve cut off there, with no point raised
further, as a result: it is what is left when the margin allows no more.
A final test that scores more than 3 % under the same settings' soak a few
minutes earlier, at the same clock, is reported as disturbed: another
program was using the card. The Optimize page asks to close other programs.
Hardware check 75 on the reference RTX 4070: the run went through in 32
minutes and saved core +135, mem +1600, 2850 MHz at 1035 mV, fans 52 %.
Its clean numbers are the undervolt step's soak, 5725 it/s on 172 W against
5641 it/s on 194 W at stock (1.5 % more score, 11 % less power); the final
test itself was disturbed by an emulator on 11 % of the card and read 6 %
low. The run from the window is still to do.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd as hardware check 76 A run from the window with nothing else on the card (no process above 0.5 % of its 3D engine), 34 minutes: core +135 MHz, memory +1500 MHz, power limit 105 %, the overclock's curve cut off at 2850 MHz and 1035 mV, fans 52 % at 70 C. Five minutes at stock against five minutes with it: 5728 and 5820 it/s (+1.6 %), 196 and 180 W (-8.2 %), fan speed 73 and 62 %, 67 and 71 C (the fan tune aims for 70 C; with the driver's own fan curve the same settings ran at 63 C on 176 W). README: a third result section for All in one with the result screen, the table and a picture of the run, and why its gains are smaller than those of the overclock and the undervolt alone: the two are ends of one line and this is the middle. The dashboard picture shows the result applied. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The label next to the fan speed came from the app's own curve driver, which is released for the length of a run: while the all-in-one run was setting the fans by hand to measure them, the tile read "(driver)". During a run the card now decides: a speed set by hand is the run's, shown as "(run)", or as "(measuring)" while the run tunes the fans; a card whose fans the run left to the NVIDIA driver, or handed back, reads "(driver)". After the run the app's own driver speaks again. The decision is `fan_owner` in core/fan_curve, with unit tests; the window knows the fan tune by the start of what it announces (`is_fan_tune_measurement`). Not seen on screen yet: the elevation prompt for the run was cancelled twice. Hardware check 77 is added with an empty result. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ever cuts its value off
Hardware check 77, an All in one run from the window: the tile read
"(driver)" at stock and in the undervolt step, "(run)" in the overclock
step and the final test, and during the fan tune "55 % (measur": the right
state and speed, with "(measuring)" cut off at the edge of the tile. The
word is now "(tuning)", as long as "(driver)", and a tile draws a value
that is wider than itself smaller. The new build was seen idle after the
run ("0 % (driver)"); the word itself in a fan tune was not.
That run is a second clean one for All in one: 5731 and 5781 it/s (+0.9 %),
195 and 174 W (-10.8 %), fans 72 and 55 %; the README mentions it next to
the first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on; the README says so first A run from the window that ends saved now switches apply-at-logon on itself, unless the box "Keep the result applied at every logon" on the Optimize page (shown while it is still off, ticked) is unticked. The result screen then says there is nothing left to do. Until now keeping the result was a second switch to find after the run. README: the first lines say what the app is for (one click tunes the card, then it keeps it that way), a card with the measured numbers of that one click sits above the screenshot, and "One click, then nothing" walks through the button, the before/after and what keeps the result applied, with what protects the user and the one time the app asks again (a driver update). The result of All in one comes first; the overclock and the undervolt follow as "all of the speed" and "all of the saving". Hardware check 78 on the reference RTX 4070: with apply-at-logon off, a Cool & efficient run from the window ended with it on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the cursor on the All in one card or on the Undervolt card the mouse wheel did nothing: those two panels are as tall as their text, such a panel can be a pixel short of its contents, and it then kept the wheel for itself instead of passing it to the page. No card scrolls itself, so every card now passes the wheel on. Hardware check 79: seen on both cards. The version is 0.4.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Builds on #20 (the undervolt in the app) and contains its commits; merging this one merges both.
What this adds
gao --optimize allon the command line. The result screen shows the card at stock next to the card now.gao --undervolt --on-overclock), and at a clock of the caller's choosing.core/fan_tune): the lowest fan speed, in steps of 5 %, at which the card settles at or under 5 C below the profile's limit, and a fan curve through that point.(run),(tuning),(driver)), a final test that was disturbed by another program on the card is reported, and the README opens with what one click does and what it measured.What it measured (reference RTX 4070, driver 617.14)
An overclock and an undervolt do not add up: an overclock already is an undervolt at every frequency. The undervolt on top of core +135 saved 5 W of 201 (check 74). They are two ends of one line, and All in one takes the middle.
Verification
cmake --workflow --preset ci: 348 test cases passdocs/hardware-checks.md: a flat top over a core offset (73), the undervolt on top of the saved overclock (74), All in one from the command line (75) and from the window with nothing else on the card (76), the fan tile during a run (77), a saved run switching apply-at-logon on (78), the page scrolling with the mouse on a card (79)Not verified
(tuning)itself during a fan tune (the run that showed the states still had the longer word, cut off), and a tile shrinking a value that does not fit🤖 Generated with Claude Code