Limiting NVidia GPU wattage in Linux to reduce temps in games

Limiting NVidia GPU wattage in Linux to reduce temps in games

As you may guess, I am an EVE Online player. I've been playing on and off since 2011 - EVE Online is my favorite game ever (at least, for now).

Right now I have Lenovo Legion 5 Pro (2021) as my main PC:

             .',;::::;,'.                m918@legion5pro 
         .';:cccccccccccc:;,.            --------------- 
      .;cccccccccccccccccccccc;.         OS: Fedora Linux 42
    .:cccccccccccccccccccccccccc:.       Host: 82JQ Legion 5 Pro 16ACH6H 
  .;ccccccccccccc;.:dddl:.;ccccccc;.     Kernel: 6.14.6-300.fc42.x86_64 
 .:ccccccccccccc;OWMKOOXMWd;ccccccc:.    Uptime: 4 hours, 13 mins 
.:ccccccccccccc;KMMc;cc;xMMc:ccccccc:.   Packages: 2899 (rpm) 
,cccccccccccccc;MMM.;cc;;WW::cccccccc,   Shell: bash 5.2.37 
:cccccccccccccc;MMM.;cccccccccccccccc:   Resolution: 2560x1440 
:ccccccc;oxOOOo;MMM0OOk.;cccccccccccc:   DE: GNOME 48.1 
cccccc:0MMKxdd:;MMMkddc.;cccccccccccc;   WM: Mutter 
ccccc:XM0';cccc;MMM.;cccccccccccccccc'   WM Theme: Adwaita 
ccccc;MMo;ccccc;MMW.;ccccccccccccccc;    Theme: Adwaita [GTK2/3] 
ccccc;0MNc.ccc.xMMd:ccccccccccccccc;     Icons: Adwaita [GTK2/3] 
cccccc;dNMWXXXWM0::cccccccccccccc:,      Terminal: gnome-terminal 
cccccccc;.:odl:.;cccccccccccccc:,.       CPU: AMD Ryzen 7 5800H (3.201GHz)
:cccccccccccccccccccccccccccc:'.         GPU: AMD ATI Radeon Vega
.:cccccccccccccccccccccc:;,..            GPU: NVIDIA GeForce RTX 3070
  '::cccccccccccccc::;,.                 Memory: 11334MiB / 30926MiB 

The cooling system is fine, but I still wanted to somehow reduce noise and cool my laptop by limiting CPU & GPU wattage - the summer is coming, after all. It could get pretty hot.

I've launched EVE Online with DX11, external screen, dGPU, VSync on, no upscaling, all high, all Effects are toggled on, Jita 4-4 hangar:

After that, I switched to EVE Online window and let the system sit for 5 minutes to get max load - yeah, for some reason dock in Jita 4-4 is the most demanding place in the game for me (granted, I haven't been in a huge fights in, like, 4 years or so). The btop++ shows the following specs after a few minutes:

1350 MHz on GPU Core

With 1350 MHz I had a:

  1. 91 watt and 82 degrees Celsius on GPU
  2. CPU was quite toasty too - 80 degrees Celsius, 3.2 GHz
  3. 60 FPS in game.

Here is the result for slight downclock to 1170 MHz:

1170 MHz on GPU Core
  1. 79 watt and 76 degrees Celsius on GPU
  2. 76 degrees Celsius on CPU with the same load (ignore 2.6 GHz mark, it was running 3.2 GHz)
  3. 58 FPS in game.

How to downclock my laptop GPU then?

  1. Get all available clocks via following command:
sudo nvidia-smi -q -d SUPPORTED_CLOCKS

Note highest value for Graphics value in MHz - for my RTX 3070 (125W) it is "2100 MHz", lowest is 405 MHz.

  1. Set GPU Core clock with:
sudo nvidia-smi --lock-gpu-clocks=LOWEST_CLOCK_VALUE,HIGHEST_CLOCK_VALUE
  1. Run a benchmark, note your GPU wattage - it should change due to clock limit.
  2. Reboot your PC to return to default values.
  3. If you want to make these changes persistent, create a systemd unit file that contains something like this in /etc/systemd/system (name it "nvidia-clock-lock.service"):
[Unit]
 Description=Set NVIDIA GPU Clock Lock
 After=multi-user.target
 
 [Service]
 Type=oneshot
#1350 = 91 W
#1170 = 79 W
 ExecStart=/usr/bin/nvidia-smi --lock-gpu-clocks=405,1170
 ExecStartPost=/usr/bin/nvidia-smi -pm 1
 RemainAfterExit=yes
 
 [Install]
 WantedBy=multi-user.target

Change first argument to the lowest desired value and second to the highest desired value from supported clock frequency list. Run

sudo systemctl daemon-reload
sudo systemctl enable nvidia-clock-lock.service

Voila, now the following service will set GPU clock frequency on every start of your system.

Keep in mind that I have back of my laptop slightly elevated with special "legs" that folds and unfolds. That really helps with cooling performance. Also you can turn off the CPU boost - it's useless and adds a LOT of heat, at least in my use cases.

P.S.:

After disabling CPU boost via

echo "0" | sudo tee /sys/devices/system/cpu/cpufreq/boost

I had a little lower temps:

0:00
/1:13

A quick fight vs CalMil pilot. Not lower FPS due to recording via NVENC.