foucault / nvfancontrol

NVidia dynamic fan control for Linux and Windows

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Implement hysteretic fan control

commonquail opened this issue · comments

I need temperature hysteresis for my fan control, because the vendor thought it might be fun to start fans only at stable low-load usage so they could market "our fans literally don't even run" as "0db", at the cost of those fans being completely bloody insufferable as soon as you do anything at all.

Here are some resources:

I think the Preisach model is the simplest general explanation but it's not accurate for this problem.

I've hacked something together that works OK for my purposes and I was planning to submit that for consideration after I've had time to clean it up. I'm not entirely satisfied with the behaviour, however, and this opens up for a bunch of questions about which of many possible ways it ought to work, where exactly it ought to be implemented, and most importantly, whether it's even desirable at all.

So let's start with the last question. I need temperature hysteresis, and I'm willing to work (a little) for it. Do you want it?

There is a certain degree of hysteresis when turning fans off but it uses "seconds below threshold" as a criterion to stop adjusting fans further. Typically this will cool the GPU an additional 2-3°C depending on load. As a first step it would be nice that at least configurable of sorts. Could you please describe a use case where a precise temperature hysteresis would be beneficial?

From guru3D user Unwinder, who made Rivatuner and MSI Afterburner:

it greatly minimizes unwanted and too frequent fan speed fluctuations when the temprature is floating around step points.

The time based control seems to only change from manual to automatic adjustment, and after about 4 minutes. That's not the functionality I need and time is not a reliable variable on which to build it. In fact, I specifically need to avoid automatic fan control because that's what's insufferable, so while I understand why Nvfancontrol switches back to auto (it's safer) it gave me some unexpected difficulty.

It's not so much about how hot the GPU runs or for how long the fans run but rather whether the fans keep re-triggering the same curve step, which happens because the fans usually cool down the GPU faster than the GPU heats up and then slow down.

OK that sounds reasonable. It was set to auto because typically this either switches the fans off or keeps them at the minimum (in some GPUs fan shut-off is not possible at all). It's really frustrating the way different firmwares are implemented and it's a shame that there is no unified way of dealing with fans.

What would be a common scenario for hysteretic temperature control? I have no problem integrating such functionality as long as it's option-gated and not enabled by default. I just want to understand a bit better how the fans would behave in such case.

It's really frustrating the way different firmwares are implemented and it's a shame that there is no unified way of dealing with fans.

And it really doesn't seem like a problem that needs to be solved anew over and over again. :/

I just want to understand a bit better how the fans would behave in such case.

Situations that cause fans to suddenly generate a lot of extra noise. For example, when my fans turn on they grunt, or if they move from something like <30% to >=50% the volume increases markedly. However, the increased fan activity then quickly cools the GPU down below the threshold and slows down accordingly, but since the load generating activity didn't stop the GPU heats up again; rinse and repeat. A profile with very steep increases is especially likely to cause this fluctuation.

Instead, the control I'm requesting here would create a window for the GPU to lose heat without slowing down the fan. It is up to the user to combine that with fan curves to create a configuration that is stable in the face of fan activity and ambient temperature.

What I made is a sort of rolling window. Every time the GPU temperature x increases above the most recently recorded maximum xmax, record that temperature instead, along with a window minimum xmin = xmax − k for some hysteresis setting k, and set the fan speed for x. If x ever drops below xmin, set xmax as before but this time leave xmin unset so the temperature can keep decreasing without getting stuck in another window, and set the fan speed for x. As long as xmin < x ≤ xmax, leave the thresholds alone and set the fan span for xmax. This seems to work OK for me but it's somewhat clumsily wired in, and always active although easy to set up like FanFlickerFix. Note that I first updated xmin whenever xmax updated and that didn't work so well; fans would get stuck in some over-active setting for prolonged periods of time.

There may be a conceptually simpler model in accompanying every curve step p with a slow-down threshold plo = p − k. I don't know if that's easier to make or if it really is easier to reason about, and I certainly don't know how it would perform. If I would to build it from scratch now, I believe this is what I would attempt, in FanspeedCurve or by making FanspeedCurve into something like a decorator.

I don't know exactly how MSI Afterburner implements its version.

OK I guess it makes sense so if you're willing to work on it please do since you've already done some work. No need to duplicate efforts.