FeralInteractive / gamemode

Optimise Linux system performance on demand
BSD 3-Clause "New" or "Revised" License
4.67k stars 184 forks source link

Gamemode doesn't detect 13600KF as big.LITTLE properly #451

Closed kostadinsh closed 8 months ago

kostadinsh commented 8 months ago

Describe the bug Gamemode doesn't seem to detect my 13600KF as big.LITTLE properly and thus doesn't pin the task to the P-cores only.

Dec 19 20:11:40 fedora gamemoded[3392]: cpu L3 cache was uniform, this is not a x3D with multiple chiplets
Dec 19 20:11:40 fedora gamemoded[3392]: cpu frequency was uniform, this is not a big.LITTLE type of system
Dec 19 20:11:40 fedora gamemoded[3392]: I can find no reason to perform core pinning on this system!

To Reproduce Steps used to reproduce the behavior:

  1. run gamemoded -t on a system with a big.LITTLE cpu (Intel Alder or Raptor Lake)
  2. View journalctl --follow
  3. See error

Expected behavior Gamemode correctly detects my cpu and pins the tasks to the P-cores

System Info (please complete the following information):

Additional context Add any other context about the problem here.

cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_max_freq
5100000
5100000
5100000
3900000
3900000
3900000
3900000
3900000
3900000
3900000
3900000
5100000
5100000
5100000
5100000
5100000
5100000
5100000
5100000
5100000
patatahooligan commented 8 months ago

Same error:

CPU: 13600K OS: Arch linux (rolling, updated on 2024-01-02) Gamemode version: 1.8.1 (Arch official repo)

Reproduced by running glxgears.

I ran a modified command as the one in the OP to show the frequencies in order and with the path in the output.

$ grep . /sys/devices/system/cpu/cpu{?,??}/cpufreq/cpuinfo_max_freq     

/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq:5100000
/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_max_freq:5100000
/sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_max_freq:5100000
/sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_max_freq:5100000
/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_max_freq:5100000
/sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_max_freq:5100000
/sys/devices/system/cpu/cpu6/cpufreq/cpuinfo_max_freq:5100000
/sys/devices/system/cpu/cpu7/cpufreq/cpuinfo_max_freq:5100000
/sys/devices/system/cpu/cpu8/cpufreq/cpuinfo_max_freq:5100000
/sys/devices/system/cpu/cpu9/cpufreq/cpuinfo_max_freq:5100000
/sys/devices/system/cpu/cpu10/cpufreq/cpuinfo_max_freq:5100000
/sys/devices/system/cpu/cpu11/cpufreq/cpuinfo_max_freq:5100000
/sys/devices/system/cpu/cpu12/cpufreq/cpuinfo_max_freq:3900000
/sys/devices/system/cpu/cpu13/cpufreq/cpuinfo_max_freq:3900000
/sys/devices/system/cpu/cpu14/cpufreq/cpuinfo_max_freq:3900000
/sys/devices/system/cpu/cpu15/cpufreq/cpuinfo_max_freq:3900000
/sys/devices/system/cpu/cpu16/cpufreq/cpuinfo_max_freq:3900000
/sys/devices/system/cpu/cpu17/cpufreq/cpuinfo_max_freq:3900000
/sys/devices/system/cpu/cpu18/cpufreq/cpuinfo_max_freq:3900000
/sys/devices/system/cpu/cpu19/cpufreq/cpuinfo_max_freq:3900000

There is no config in /usr/share or /etc. $HOME/.config.gamemode.ini has exactly the following contents.

[cpu]
park_cores=no
pin_cores=yes
patatahooligan commented 8 months ago

I dug a bit through the code and this seems weird to me

https://github.com/FeralInteractive/gamemode/blob/5180d89e66830d87f69687b95fb86f622552b94b/daemon/gamemode-cpu.c#L137-L138

As I understand it the above lines are supposed to figure out if we should keep the core we are currently iterating over. But the condition would always evaluate to false. At this point freq <= max_freq and cutoff > 0, so obviously freq - cutoff < max_freq for all cores.

I'm guessing it should have been

if (freq + cutoff >= max_freq)
    CPU_SET_S((size_t)cpu, CPU_ALLOC_SIZE(info->num_cpu), freq_cores);

I'll try it out and open a PR if it works.

kostadinsh commented 8 months ago

I tested the PR, and it still seems to not pin the processes to the P-cores, looking at htop, the load is distributed across all of them.

patatahooligan commented 8 months ago

@kostadinsh I found that I had to reboot after installing a new gamemode version for the change to take effect. I imagine it's because the daemon persists in the background. Did you reboot before testing it?

Also can you check the daemon logs for anything related to core pinning, and the process affinity with taskset -ap $PID?

kostadinsh commented 8 months ago

@patatahooligan you were correct, after a reboot it pins it to the right cores properly. Sorry for the noise and thanks for fixing the issue. :-)

HenrikHolst commented 3 weeks ago

Thanks for finding and fixing this bug, one of the problems with not having access to the actual CPU that the code should detect...