You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit dbeceb6
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: README.md
+15-1Lines changed: 15 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,6 +28,7 @@ GPU Auto Optimizer tunes the **power limit** and the **core and memory clock off
28
28
-**Stays applied:** the tray app re-applies the tune at every logon, and within about half a minute after a driver reset (TDR).
29
29
-**Fan curves:** Silent, Normal, Cool or Aggressive with any profile, or your own; fans stop at idle without cycling on and off, the app learns the lowest speed your fans can actually hold, and the fans go back to the driver on exit, sleep, logoff and crashes.
30
30
-**Plays fair:** if MSI Afterburner or another tool changes the settings, it steps aside instead of fighting over them.
31
+
-**Updates itself:** a quiet line at the bottom left says when a new version is out; one click downloads it, checks it and restarts the app. Nothing pops up, and nothing is installed without that click.
31
32
-**Native and small:** two C++ programs, under 2 MB together, with no installer, no runtime and no driver or service.
32
33
33
34
## One click, +4.5 % performance, with a safety margin
@@ -72,7 +73,7 @@ Turning on **Apply at logon** copies the app to `%ProgramFiles%\GpuAutoOptimizer
72
73
73
74
| | |
74
75
|---|---|
75
-
| OS | Windows 10 or 11, 64-bit |
76
+
| OS | Windows 10 (version 1803 or later) or 11, 64-bit |
76
77
| GPU | NVIDIA, Pascal (GTX 10-series) or newer, with a current driver |
77
78
| Rights | Administrator to optimize or apply; reading telemetry does not need them |
|`gao --stress <seconds>`| Runs the stress test alone and prints its verdict; changes nothing |
124
125
|`gao --bandwidth`| Measures the current memory bandwidth |
126
+
|`gao --update`| Installs the latest release into the folder `gao.exe` is in, if there is a newer one |
125
127
|`gao --stress-recreate`| Runs the stress test, rebuilds its GPU device, runs it again; prints both scores and the rebuild time; changes nothing |
126
128
127
129
Ctrl+C during `--optimize` restores stock.
128
130
129
131
## FAQ
130
132
133
+
<details>
134
+
<summary><b>Does it connect to the internet?</b></summary>
135
+
136
+
Only to look for a new version: one request to `api.github.com` when the app starts and once a day after that. Nothing but the request itself is sent. You can switch it off under **About**. An update is downloaded only when you click **Update available** (or run `gao --update`): the zip comes from this project's GitHub releases over HTTPS and is installed only when its SHA-256 matches the one GitHub publishes for it.
137
+
</details>
138
+
139
+
<details>
140
+
<summary><b>How do I move to a new version?</b></summary>
141
+
142
+
From 0.3.1 on, click **Update available** at the bottom left of the window. From an older version, download the zip and start `GpuAutoOptimizer.exe` from it: it offers to replace the older copy that runs in the tray, and it updates the copy that starts at logon by itself.
143
+
</details>
144
+
131
145
<details>
132
146
<summary><b>Does it work alongside MSI Afterburner?</b></summary>
Copy file name to clipboardExpand all lines: docs/development.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -34,6 +34,7 @@ src/core/ pure logic: no windows.h, no driver calls, no D3D. Unit-tested in
34
34
boot.* when a logon apply may run (strikes, driver, card) and the verified apply
35
35
watchdog.* the tray app's decisions: re-apply, give up, back off, driver changed
36
36
task_xml.* the logon task definition
37
+
update.* reading GitHub's "latest release" answer; version numbers
37
38
fan_curve.* fan curves, the per-second controller and the FanDriver
38
39
src/hw/ the only code that touches hardware or the OS state folders.
39
40
nvml.* telemetry and power limit via NVML
@@ -42,6 +43,7 @@ src/hw/ the only code that touches hardware or the OS state folders.
42
43
stress.* the DX11 compute load; the GPU checks every value it computes
43
44
app_files.* gao.json (atomic writes), the crash journal and boot.log, flushed to disk
44
45
boot_task.* the logon task and the Program Files copy
46
+
update_io.* what an update needs from Windows: HTTPS download, SHA-256, unzip, file version
45
47
src/app/
46
48
common.* logic both programs share: optimize, logon apply, apply-at-logon on/off
47
49
main.cpp gao.exe, the command line
@@ -84,6 +86,9 @@ The applied offset is always at least one step below the confirmed edge. Profile
84
86
| No undervolting | Locking a voltage point hard-froze the reference RTX 4070, and reshaping the curve gave no measurable gain on a power-limited card. |
85
87
| Fans through NVML, stop zone via the driver | NVIDIA's legacy NVAPI fan API is gone on RTX 20-series and newer; NVML's `nvmlDeviceSetFanSpeed_v2` is public and verified by reading the target back. Below the stop threshold the driver owns the fans, so no failure of this app can leave them stopped. |
86
88
| Tray app plus logon task | Driver settings are volatile: a reboot or driver reset clears them. The logon task starts the tray app, whose watchdog keeps the tune applied; three crashing logons in a row switch it off. |
89
+
| An update is one click, and never more than that | The app asks GitHub for the latest release (`core/update`) and shows one line in the sidebar; nothing is downloaded until it is clicked. The zip must come from this project's releases over HTTPS and match the SHA-256 the GitHub API publishes for it, and both executables in it must carry the version the release claims. Elevated, the download is unpacked under `%ProgramData%\GpuAutoOptimizer\update`, which only administrators can write, so nothing can be swapped between the check and the copy. The executables are replaced where they run from (a running one is renamed aside) and the app starts again with `--resume`, which keeps a tune that is applied under the watchdog. The trust this rests on is the GitHub account: the executables are not code-signed. |
90
+
| A newer copy takes over from an older one | The app is single-instance, and the copy in the tray usually runs elevated. A copy that is started later reads the running one's version from a window property (builds before 0.3.1 have none and count as older) and, when it is newer itself, offers to replace it: it starts again elevated with `--replace`, asks the old copy to exit through its own tray-menu command (which hands the fans back and stops a run cleanly) and ends it only when it does not go and no optimize run is under way. An elevated start from outside Program Files also replaces the logon copy when apply-at-logon is on and that copy is not newer (`update_logon_copy`): a profile saved by a new build must be one the logon copy accepts. |
91
+
| A logon apply that ends cleanly is no strike | Strikes count logons that may have crashed the machine. An apply that was refused before any write, or failed and reset the card to stock, did not: the strike it recorded up front is taken back. Only a failed reset keeps it. Before 0.3.1 three refused logons read as `disabled after 3 crashes`. |
87
92
| Dear ImGui on DX11 | One small binary with no runtime, and the D3D11 device is in the process anyway for the stress load. |
88
93
89
94
**Not yet verified on hardware.** The handling of a driver reset during an optimize run (the rows above on the reconnect, the in-probe `STALLED`, the reset budget, the rest and health check, and the memory-first single-step search) describes what the code does. It is implemented and unit-tested. On hardware only this much has been seen, in round A of [hardware check 51](hardware-checks.md), on a build that reconnected but took no rest: `gao` survived a forced reset, reconnected and left the journal clean, and the desktop was unusable afterwards. Whether the rest keeps the desktop usable is not known.
Copy file name to clipboardExpand all lines: docs/hardware-checks.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -83,6 +83,10 @@ root; adjust the path for a Debug build.
83
83
| 54 | The window after its display device went away (the incident) | First exit the tray app that is running (tray menu, Exit) and confirm in Task Manager which executable is running: the app is single-instance, and a second `GpuAutoOptimizer.exe --tray` returns at once without a message, so the running build's behaviour would be recorded as the new build's. Then start the build under test, once, as the logon task starts it (elevated, `--tray`) and never open the window: on the first run the installed v0.2.0 (`GpuAutoOptimizer.exe --tray` from an elevated shell in its install folder), on the second run the new build (`.\build\Release\GpuAutoOptimizer.exe --tray` from an elevated shell in the repository root); reinstall the NVIDIA driver (or disable and enable the display adapter in Device Manager); click the notification or the tray icon | yes (tray) | the process is still running; no new `crash-*.dmp` in `%ProgramData%\GpuAutoOptimizer`; the desktop is usable within one minute after the reset (the windows that were open are visible and usable, a new program can be started and shows its window, no sign-out or restart was needed, programs that crashed are noted); the owner's judgement: the machine feels normal afterwards. The window opens and keeps updating. Run it on the installed v0.2.0 first and record whether the crash reproduces there: without that, a pass on the new build proves nothing. | |
84
84
| 55 | A reset with the window open | First exit the tray app that is running (tray menu, Exit) and confirm in Task Manager which executable is running: the app is single-instance, and a second start returns at once (with `--tray` without a message; without it, it only brings the running window forward), so the running build's behaviour would be recorded as the new build's. For the new build, start `.\build\Release\GpuAutoOptimizer.exe --tray` from an elevated shell and open the window from the tray icon. With the window visible and no search running, force a driver reset: `dxcap -forcetdr` | yes | the process is still running; no new `crash-*.dmp` in `%ProgramData%\GpuAutoOptimizer`; the desktop is usable within one minute after the reset (the windows that were open are visible and usable, a new program can be started and shows its window, no sign-out or restart was needed, programs that crashed are noted); the owner's judgement: the machine feels normal afterwards. The window comes back within a few seconds and keeps updating; the Windows System log shows exactly one driver reset, the forced one. Whether this passes on v0.2.0 is not known (row 33 ran with the window hidden, where nothing is drawn): run it on v0.2.0 first as well and record the outcome. One more observation to record: recovery of the window's device now clears and flushes the old device context before creating the new one; record whether the window gets its picture back, because whether that works on a removed device is not known. | New build: Pass (2026-10-04, reference RTX 4070, driver 617.14, build 2d9d115, started elevated without `--tray`, so the window opened by itself; no other tray app running; no search running; driven by a script that kept the window above the other windows, took screenshots of the screen and ran `dxcap -forcetdr`). Before the reset the window showed the dashboard with changing telemetry (core 2490 then 210 MHz). 5 s, 15 s and 40 s after the reset the window showed the dashboard again and the telemetry kept changing (core 210, 780, 210 MHz; power 14, 33, 17 W). The process was still running after 40 s; no new `crash-*.dmp`; Windows System log: three nvlddmkm 153 events within one second, the forced reset, and nothing else; a new program started and showed its window after 0.5 s, no window was gone. Not observed: whether the window lost its picture in the first seconds (the first screenshot is from 5 s after the reset). In a first attempt the window was covered by other windows and is on none of the screenshots; the process survived that reset too. Not run on v0.2.0. The owner's judgement is not recorded. |
85
85
| 56 | A reset during a run started from the window | Exit the running tray app first and confirm the executable, as in 54; start `.\build\Release\GpuAutoOptimizer.exe` from an elevated shell, pick Best, Optimize; once the core climb runs (`core +15 / mem +N`, `core +30 / mem +N`, ... in the window's log), run `dxcap -forcetdr` from an elevated shell; after the `health:` line, press Abort | yes | the window's picture comes back; the window's log continues through `preparing the stress load` and a `health:` line; the Abort button works afterwards (the run ends with `aborted`, card at stock); the process is still running; no new `crash-*.dmp` in `%ProgramData%\GpuAutoOptimizer`; the desktop is usable within one minute after the reset (the windows that were open are visible and usable, a new program can be started and shows its window, no sign-out or restart was needed, programs that crashed are noted); the owner's judgement: the machine feels normal afterwards; the Windows System log shows exactly one driver reset, the forced one. | |
86
+
| 57 | A refused profile at logon is no strike | set `"mem_mhz": 99999` in the profile of `gao.json`; start `GpuAutoOptimizer.exe --tray` elevated; read the last line of `boot.log` and `boot_strikes`; restore the value | yes |`apply failed: profile values out of range; nothing applied`, and `boot_strikes` is what it was before | Pass (2026-10-05, reference RTX 4070, driver 617.14, build abc6419). `boot_strikes` 0 before; the tray start logged `apply failed: profile values out of range; nothing applied`; `boot_strikes` 0 after. With the copy installed before (a build of 2026-09-27) the same refusal at a real logon had left `strikes: 1 of 3` five minutes later. |
87
+
| 58 | The logon copy follows a newer build | with apply-at-logon on and an older copy in Program Files, start the new `GpuAutoOptimizer.exe` elevated from its build folder; `gao --status`| yes |`boot copy: up to date`; both installed executables carry the new version; a copy with a higher version is left alone | Pass (2026-10-05, same machine and build). Before: `boot copy: OUTDATED`, installed 0.3.0. After the elevated start: `boot copy: up to date`, `gao.exe` and `GpuAutoOptimizer.exe` in Program Files version 0.3.1. Not checked: that a newer installed copy is left alone. |
88
+
| 59 | An older copy in the tray is replaced | with the released v0.3.0 `GpuAutoOptimizer.exe --tray` running elevated, start the new `GpuAutoOptimizer.exe` unelevated; answer Yes, accept the elevation prompt | no, then yes | a question `An older version of GPU Auto Optimizer is running in the tray. Replace it with version N?`; after Yes and the prompt the old process is gone, the new window is open, the tune is still applied and `boot.log` shows the old copy's own exit (its strike cleared) | Pass (2026-10-05, same machine and build). The running window had no version property; the question appeared; five seconds after Yes the app window belonged to a new process with version property 0.3.1 and was visible; one `GpuAutoOptimizer.exe` process; `boot.log``ran 2 minutes without a crash; strike cleared` from the old copy's exit; `applied: power 105 %, core +135 MHz, mem +1600 MHz`; `strikes: 0 of 3`. Not checked: No as the answer, and a replace while the old copy runs an optimize. |
89
+
| 60 | The app updates itself | a build whose version is set below the latest release, in a folder of its own: start `GpuAutoOptimizer.exe`, wait for `Update available` at the bottom left, click it; and `gao --update` from the same kind of folder | no | the line appears within seconds of the start; after the click both executables in the folder are the release's, the old running one is renamed aside, and the app is running again as the new version; `gao --update` prints the version found and `updated to version N`, exit 0 | Pass (2026-10-05, same machine; a build of abc6419 with the version set to 0.2.9, latest release v0.3.0, unelevated, in a temporary folder). Window: `Update available` showed with the tooltip `Version 0.3.0 is available (this is 0.2.9).`; five seconds after the click a new process ran from the same folder with file version 0.3.0, `gao.exe` and `GpuAutoOptimizer.exe` were the release's sizes and version, and `GpuAutoOptimizer.exe.old-N` was the 0.2.9 copy. Command line: `version 0.3.0 is available (this is 0.2.9); downloading`, `updated to version 0.3.0`, exit 0; with the current version `up to date`. The installed copy, elevated (the same 0.2.9 build copied into Program Files and started with `--tray`, as the logon task does; the window opened and the line clicked by a script): five seconds after the click a new process ran from Program Files with file version 0.3.0; both installed executables were 0.3.0; the running one had been renamed aside; `%ProgramData%\GpuAutoOptimizer\update` was gone again; `applied: power 105 %, core +135 MHz, mem +1600 MHz`; `strikes: 0 of 3`, the old copy having cleared its strike on the way out. Not checked: a download that does not match its SHA-256, and an update from 0.3.1 to a later release (there is none yet), which is the first that restarts with `--resume` into a build that knows the flag. |
0 commit comments