-
Notifications
You must be signed in to change notification settings - Fork 190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an option for using a different governor for integrated GPUs #179
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, Jason, this is an awesome investigation and PR. Apologies if my code had been hurting performance on integrated chips up until now. Perhaps that's a callout to implement some smaller benchmarking backend to make sure no changes here cause problematic perf for a number of setups.
You make a good argument that this is the most pragmatic solution for now, but were you able to confirm that once we hit this power threshold and swap back to powersave
we don't hit the CPU-based frame pacing issues that plagued that governor? The protective factor might be that when the threshold is met, the GPU is doing some significant amount of work, so in practice, that may not be a situation where there'd be worry about feeding the GPU more work.
Anyway, I've added some minor feedback, but the jist of the PR seems solid enough that it'd be great to merge.
|
||
double ratio = (double)igpu_energy_delta_uj / | ||
(double)cpu_energy_delta_uj; | ||
if (ratio > threshold) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In your input you mention that it'd be possible to be leveled at about the threshold, causing a flip flop. Would it make sense to have an allowance for the threshold? I'm unsure what the variance over time of these energy deltas looks like, so I don't know what the value should be, but maybe it could look something like this:
const double buffer = 0.1f;
if( ratio > threshold + buffer ) {
// GAME_MODE_GOVERNOR_IGPU_DESIRED
} else if ( ratio < threshold - buffer ) {
// GAME_MODE_GOVERNOR_DESIRED
} else {
// Leave as before
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's possible but I think ultimately unlikely. Once you go above the threshold, it switches to the powersave governor at which point the power used by the CPU is likely to significantly decrease making the ratio even larger so there's a natural bias in the system which does exactly what you want. Unfortunately, I'm not sure how reliable that is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that makes sense. It might be prudent to try and graph how long the response time on that switch is, but given our current polling rate is 5 seconds by default we're likely in the clear.
Typically, with an integrated GPU, feeding it isn't nearly as much of an issue. Even with our latest GPUs (Ice Lake is significantly more powerful than anything we've shipped previously), a game like Tomb Raider can typically keep it fed without requiring the full CPU power budget to do so. In my experiments with SotTR, I was able to limit my CPU to as low as 500-600 Mhz without hurting graphics performance. Of course, that's just one game and one laptop, but I think the point still stands that when trying to get the best performance, the GPU is typically going to be the throttle point with Integrated graphics. Also, it's worth pointing out that the names "performance" and "powersave" are somewhat misunderstood these days. The "powersave" of today is not at all the same as the "powersave" of yesteryear when we had the 5 different governors. The "performance" governor basically means "give me maximum performance at all costs" whereas the "powersave" governor isn't "save power at all costs; I'm on battery", it's a more balanced "don't burn more power than you need to." My understanding (I may be wrong) is that we've been recommending the "powersave" governor for basically everything including desktops, laptops that are plugged in, and servers. It's not quite as eager to scale up as "performance" but it should give just as much performance in the aggregate. None of that really answers the question of frame pacing issues. With a discrete GPU, you want the CPU to immediately jump into action the moment the GPU is ready for more work. With an integrated GPU, you want this as well but you don't want it at the cost of your power budget. Because the CPU governor is still the one in control today, if the game starts doing significant CPU work, the CPU will clock up and take power from the GPU if it needs to do so; it just won't over-compensate like it does with "performance". The balancing issues are something we're investigating but any improvements there are going to be in the kernel pstate code and a prerequisite for that working is for gamemode to stop forcing the CPU governor into super-aggressive mode. |
Great, you've cleared up my worries.
Good to hear this. Shifting GameMode away from messing with the CPU governor is a wish of mine as well - |
This still has me a bit worried. Is the pop-up notification expected in some setups or is it just a weird thing that I'm experiencing because I'm running a development build? I'm just building with |
That happens sometimes if you reinstall without restarting polkit. Should go away if you restart it. Might be worth adding |
I'll add a commit for that. |
4f80b4d
to
8780f0e
Compare
I think I've addressed all the comments at this point. However, before we land anything, I'd like to play around with my laptop pile a bit and see what I think of that 0.5 figure for the default threshold. It mostly seems to work on my Ice Lake but every laptop is going to be different. |
I dug through my entire Laptop pile and ran some tests with power measurements this afternoon. On each laptop, I tested the following:
I ran each of those tests on the following hardware:
While I don't think I can actually share my raw data (we have rules about that sort of thing), I think I can share the following findings:
|
Few minor comments:
|
Good point. Maybe it's a better idea to check the power consumption with Intel RAPL instead of the GPU usage? Meaning to switch to a different governor only if the you hit the TDP limit, and if the gpu usage is lower than ~70% for example. Maybe this code helps for implementing: https://github.com/kitsunyan/intel-undervolt |
Yes, I'm aware that i965 and some of the unigine benchmarkes have some CPU stalling issues particularly with unsynchronized maps. However, my objective of these explorations was to get a rough idea of how much power the GPU burns under load. For this, it was more important to get something which lights up as much of the GPU as possible rather than something which is guaranteed to be GPU limited. If it's not 100%, that's fine. Again, I'm going for "rough idea" here not an exact measurement of max GPU power consumption.
Sure, if you're gaming on a desktop GT2, powersave may not get you any better throughput. However, even with a 100W+ TDP, if you have a GT3 or GT4 in a desktop with good cooling, you can still end up TDP limited. You probably have to be running the CPU pretty hard to get there but that's exactly what the performance governor does (run things hard). 😄
That is true and also completely irrelevant to this MR.
That probably works but it also requires running with ftrace and polling CAGF at a fairly high rate. Those two things are likely to put additional CPU load on the system and possibly make any power problems we have worse.
Yes, and if the data hasn't been calibrated, the RAPL driver in the kernel won't expose anything via sysfs and the code in this MR will log the lack of RAPL data and fall back to the old gamemode behavior. When the user finally does get a new enough kernel, the iGPU stuff will kick on and they'll start getting better perf.
Sure. However, I doubt USB or whatever other things they put on "uncore" burn that much power. It's close enough that our power management people have labled it "GFXWatt" in turbostat....
If some user wants to play with that, they're more than welcome to. However, I'm happy to leave pstate tuning up to our (Intel's) power management people. Right now the problem we have is that gamemode is overriding that tuning and throwing it into "burn all the power" mode. I'm not sure what if anything from that list of bullet points is actionable. I'm not going to claim that looking at GPUWatt/CPUWatt is the best solution for over-all power management. However, it does seem to be fairly effective way to detect when the iGPU is under non-trivial load so gamemode will stop overriding the pstate driver and throwing the CPU into "burn all the power" mode. If we want to do finer tuning of pstate based on GPU usage, that really needs to happen in the kernel. |
That doesn't work. The TDP reported by BIOS and exposed via RAPL isn't the actual power at which things will start throttling. On my laptop, for instance, the BIOS reports a TDP of 35W even though the chip is only rated at 25W and actual throttling happens even lower yet. Throttling can happen due to any number of reasons including BIOS limits, motherboard power delivery limitations, cooling limits, internal chip limits, and others. The BIOS limit we have via RAPL is only one of the many limits. There's no way to objectively ask from software "Am I using 70% of the available power?" without significant tuning to your specific machine. Maybe for laptops one could build a database but that's not a practical general solution. |
Thanks Jason, my vote goes to this more pragmatic solution as is. The thing is, philosophically, the more complicated you go in analyzing the details and reacting to them, the harder it becomes to understand the emergent behavior of the system. It also becomes incredibly easy to introduce unknown edge cases with very bad issues, rather than a simpler set of known cases with easier to handle problems. I'd prefer GameMode stays on the simpler side, and we leave the more complicated things to driver code that has a much better handle on it's entire problem space. TL;DR: Less code is more. |
Well that isn't RAPLs fault but from lazy manufactors. However, you're right if things like this are common it doesn't make sense to use it. What also would be possible instead of just assuming that one uses an integrated GPU is a script that checks during install weather the machine uses an iGPU or not, and changes the Maybe something like this: if $(glxinfo | grep -q Intel); then
# change default config
fi While |
At least on my desktop CPU which has an integrated GPU but is disabled (i7-9700K), I don't see an "uncore" RAPL entry in sysfs (only have "core" and "dram"). As far as I can see, if uncore isn't present, then we'll fall back to the original behaviour. I think it can also be disabled by setting igpu_power_threshold to a very large number in the config such that the threshold is impossible to meet. Perhaps that could be documented in the example config.
While this may work for installing from source, it wouldn't help for distro packages unless they all made sure their post install scripts did this. I don't think it's reasonable to expect that to be done, plus it's also entirely possible that the package installation is being done from an environment where glxinfo won't work (anywhere $DISPLAY isn't set). |
You can still have the iGPU enabled without using it as your main graphics card, for example to power a secondary monitor. Most mainboards disable the iGPU by default if a GPU is installed, some don't. Relying on this is not a very clean solution imho.
But isn't it pointless then to check the power threshold all the time? It shouldn't be too hard to add a option to the config file to disable this.
Distro packages are a problem here, that's true. Using glxinfo was just an idea, one could also use for example Edit: at least for me it sadly doesn't work with hybrid GPUs, even with a fullscreen application lspci still shows the iGPU as the main one. However hybrid GPUs are an edge case anyway, with a normal discrete setup it should work fine, would be nice if someone can test this. Maybe there is a solution which is more elegant than lspci. Edit2: I did a little bit of research and found this. If one has the pid (which the daemon should know afaik), one can check which GPU the process is using. It's not super trivial, but it should be somewhat clean. First one checks if one has an iGPU, and if yes extract the PCI-ID. Then one checks with |
No, it's just reality. How much power you can burn is also determined by cooling which can be affected by things such as ambient temperature, cooling rig (not a variable for laptops), how good your thermal paste is (can change with age), and how much dust you've accumulated in your heat sink. There is absolutely no way for the manufacturer to provide accurate data for this even if they wanted to.
Set
I already thought of this. If you set it to -1, it will always use
What if your add or remove a card? What if you move your drive between machines? Any sort of install-time hardware detection is sketchy at best.
It doesn't rely on that. If you aren't using the iGPU, it will use little to no power and you'll get the old behavior. Even if you are using the iGPU but you're only using it for compositing and using the discrete GPU for rendering, the 0.3 threshold is high enough that it should consider that as being in the discrete GPU case and you'll get
Not right now but they're coming. We don't want anything to be done based on hard-coding "Is it Intel?" because that's just a ticking time-bomb.
I also considered that strategy and rejected it for two reasons: First, it's complicated and complicated things have a tendency to break in strange ways in the wild. Second, and more importantly, there's no way to guarantee that the app only opens one GPU. I think it's usually true with OpenGL that the app will only open one GPU but with Vulkan, it's not. The Vulkan loader opens every ICD on the system and presents them to the app and the app is free to pick-and-choose which devices it wants to use and possibly use both. From the perspective of |
Yes please :) Other than that, my previous comments stand. I especially agree with not assuming Intel is a iGPU. That's asking for trouble, once you add one bad assumption to a program, someone is bound to rely on that assumption elsewhere too, and be for you know it, you have computers unable to handle new millenniums. |
Ah, that makes sense.
My code is an example, you could easily test it against stuff like checking if there is "GT" inside the name, or whatever, same goes for checking AMD iGPUs btw.
Yeah that is problematic, didn't think of that. Too bad that there is no easy way to check all this stuff. |
Done.
I don't want to trust in any sort of name matching for a few reasons:
I highly doubt that RAPL will be used for discrete GPUs. So far, it's entirely used for things that are part of the CPU package and, therefore, share it's power budget. I expect if we report any power usage for discrete GPUs that it'll be reported through the graphics driver. That said, I can't make any guarantees about it so there is always the possibility that things will have to be re-thought. However, I think "if it's in RAPL it's integrated" is probably a fairly safe assumption at the moment. In general, future-proofing this for Intel discrete GPUs is tricky. What I do know is that matching "intel" is guaranteed to be wrong and any other sort of name matching is likely to be wrong eventually. |
Yeah I guess this the best option for the average user right now, stuff like hybrid GPUs or Desktop iGPU setups are probably pretty rare anyway, so better this than a hacky solution that doesn't work properly. Thanks for the work 👍 Btw @mdiluz how are the chances that 1.6 (with this merged) is released in time before the Ubuntu 20.04 import freeze in late February? Since 20.04 is an LTS it's probably used by a lot of people who game, so it would be nice to have this and the latest improvements included. |
@stephanlachnit I no longer work at Feral, so can't guarantee anything, but will ping someone who does. |
Thermal Design Power (TDP) limit set for a given chip is supposed to reflect cooling capability of the machine where it will be / is installed. If machine is getting temperature limited, I think user really needs to fix the cooling, as higher temperatures are going to degrade the CPU/iGPU faster. Fixing cooling is also one of the cheapest ways to significantly improve (and stabilize) performance. Could the daemon show some note to the user about that when it detects things being temperature limited? |
Roughly, yes. However, that doesn't mean that it actually does and that we can rely on anything the OEM decides to advertise. Also, even if your system isn't broken (clogged fan etc.) there's still going to be a difference between when it's sitting on your lap vs. a table vs. a cooling pad. My point with that comment was that the best the OEM can provide is a rough estimate. The actual cooling abilities are environmentally dependent.
No, there's no way to accurately detect that. There are too many components involved that are all trying to manage power and adjusting things up and down for various reasons. There's no way that we can reliably detect that your power management problems are due to cooling in a way that would actually be useful to users. Even if we could, this daemon would be the wrong place for that. |
There are temp & power and their limit value files hwmon sysfs, and alarm files telling whether they were triggered: However, although I see HWMon sysfs input files showing first Core and then Package temperature to get close (99C) to max/crit temperature values (100C) [1], and as results dmesg showing following for SkullCanyon:
All the alarms show still zero:
[1] I assume *_input value never hits _max/_crit value, because of throttling, one sees only it getting very close. And I assume that on this HW, alarms are triggered only if limits are exceeded. => While checking *_alarm files shouldn't be harmful, they don't seem useful on this HW. (It's easy to test in a high-end NUC, just block ventilation holes and run some heavy loads.) Then there's also: "Some computers have the ability to enforce a power cap in hardware. If this is the case, the |
@eero-t this seems like a separate feature request - could we split it into a new issue? |
I've forced over a fix for Travis CI from master just to check that all tests pass, unfortunately there's a couple of failures. Can you rebase and run I've tested this using one of our games and it behaves as expected so I'll happily merge once those issues are fixed. |
This commit adds two new configuration options: igpu_desiredgov and igpu_power_threshold which allow for a different CPU governor when the Intel integrated GPU is under load. This currently only applies to Intel integrated GPUs and not AMD APUs because it uses the Intel RAPL infrastructure for getting power information. If on a platform that without an Intel integrated GPU or where the kernel does not support RAPL, the new options will be ignored and it will fall back to the old behavior. One of the core principals of gamemoded to date has been that, when playing a game, we want to use the "performance" CPU governor to increase CPU performance and prevent CPU-limiting. However, when the integrated GPU is under load, this can be counter-productive because the CPU and GPU share a thermal and power budget. By throwing the CPU governor to "performance" game mode currently makes the CPU frequency management far too aggressive and it burns more power than needed. With a discrete GPU, this is fine because the worst that happens is a bit more fan noise. With an integrated GPU, however, the additional power being burned by the CPU is power not available to the GPU and this can cause the GPU to clock down and lead to significantly worse performance. By using the "powersave" governor instead of the "performance" governor while the integrated GPU is under load, we can save power on the CPU side which lets the GPU clock up higher. On my Razer Blade Stealth 13 with an i7-1065G7, this improves the performance of "Shadow of the Tomb Raider" by around 25-30% according to its internal benchmark mode.
0b6694f
to
5c769fd
Compare
This makes it more properly install things so that you don't get the nasty pkexec pop-ups with dev builds.
@afayaz-feral Passing now. The polkit issue was thanks to the last patch and the fact that the ubuntu container doesn't have polkit installed. I made it query for available systemd services before attempting to reboot plokit and now we're good. |
Add an option for using a different governor for integrated GPUs
Overview
This PR adds two new configuration options: igpu_desiredgov and igpu_power_threshold which allow for a different CPU governor when the Intel integrated GPU is under load. This currently only applies to Intel integrated GPUs and not AMD APUs because it uses the Intel RAPL infrastructure for getting power information. If on a platform that without an Intel integrated GPU or where the kernel does not support RAPL, the new options will be ignored and it will fall back to the old behavior.
One of the core principals of gamemode to date has been that, when playing a game, we want to use the "performance" CPU governor to increase CPU performance and prevent CPU-limiting. However, when the integrated GPU is under load, this can be counter-productive because the CPU and GPU share a thermal and power budget. By throwing the CPU governor to "performance" game mode currently makes the CPU frequency management far too aggressive and it burns more power than needed. With a discrete GPU, this is fine because the worst that happens is a bit more fan noise. With an integrated GPU, however, the additional power being burned by the CPU is power not available to the GPU and this can cause the GPU to clock down and lead to significantly worse performance.
By using the "powersave" governor instead of the "performance" governor while the integrated GPU is under load, we can save power on the CPU side which lets the GPU clock up higher. On my Razer Blade Stealth 13 with an i7-1065G7, this improves the performance of "Shadow of the Tomb Raider" by around 25-30% according to its internal benchmark mode.
Design
The design used in this PR makes some design trade-offs which may or may not be the right ones but I think it's enough to kick off the discussion. The ideal design would probably be
However, we don't actually know that information in the gamemode daemon.
The approach taken by this PR is to instead try to figure out if the integrated GPU is under a reasonably heavy load. It does this by using the Intel RAPL framework to figure out how much power is being burned by the CPU and GPU. The theory is that if the GPU is burning significant power relative to the CPU then we should use the powersave governor to try and give it more.
This approach has a number of problems:
It also has some significant upsides:
Other design ideas
When looking into this, I considered a few other ideas which I think are worth enumerating.
I'm very much open to other design ideas. I'm trying to enumerate as many as I can here to get the conversation going. However, we need to come up with something because gamemode is actively hurting performance on integrated GPUs. With distros shipping it and games enabling it in the hopes of better Linux perf, that's really bad for all the laptop users out there. 😦