1

I would like to avoid a process using too much CPU. In fact, I want to prevent my CPU from heating up since I have some really long CPU demanding tasks (video converting) to run from a Raspberry Pi with Debian on it: temperature rises over 80 °C.

I have seen that there's a cpulimit command, but I don't know how to run my command with it since it seems to take either the pid (process ID) as argument or an executable file with the code to run, not the bash command itself. I would like to directly see what my task returns and be able to Ctrl-C if needed. Note: if I try to put my task command into a file and run cpulimit -l 20 --path=/path/to/my/file.sh, then it returns Warning: no target process found. Waiting for it... So it looks like I am unable to understand 1) what the --path argument actually does, and 2) how to properly use cpulimit on any terminal command...

I would prefer not to use workarounds like nohup my-command --my-args &, even if it secondarily returns the pid and let me write the cpulimit command for it.

Thanks in advance!

wallyk
  • 248
Johannes Lemonde
  • 145
  • 1
  • 2
  • 9
  • would nice be enough? – Rui F Ribeiro Feb 27 '18 at 20:18
  • @RuiFRibeiro : I'm not sure since the point is not to prevent my task from having a kind of priority upon other tasks but to avoid too much CPU usage. Let's say I want maximum 25% of CPU usage, that means that there might be 75% unused CPU cooling down (I have 4 cores). I fear, with nice my task would use all the CPU even with the worst priority since there won't be other tasks in the same time. – Johannes Lemonde Feb 27 '18 at 20:29
  • 1
    You can limit it to one CPU for instance. There are other methods too. https://unix.stackexchange.com/questions/326579/how-to-ensure-exclusive-cpu-availability-for-a-running-process – Rui F Ribeiro Feb 27 '18 at 20:32
  • Would limiting it to only one CPU core mean that it would be always the same? To prevent overheating, I would prefer the cores to switch regularly! – Johannes Lemonde Feb 27 '18 at 20:34
  • Let´s wait for other suggestions, there are other methods. – Rui F Ribeiro Feb 27 '18 at 20:36

2 Answers2

2

Leverage the Power Management Capabilities of your Hardware

If your goal is to reduce the CPU temperature you might want to consider tweaking power management parameters to ensure the CPU gets throttled earlier. Depending on the model of your Raspberry Pi you might want to reduce the temp_soft_limit in config.txt (default seems to be 60°C). See the Raspberry Pi documentation for details.

Use Control Groups

Another option would be to use cgroups to limit the amount of resources a process can use. Note that cgroups also takes child processes into account a process might spawn and can also be applied to daemons. If you want to limit CPU usage by let's say your favorite shell which spawns tools like sed, awk etc. or the Chrome browser which spawns a separate process for each tab this would set a limit for the amount of CPU cycles all processes in the affected cgroup can burn.

You can create a control group with name "cpulimit" like so:

$ sudo cgcreate -g cpu:/cpulimit

Set the limit for the processes in this control group to 20% of the CPU time:

$ sudo cgset -r cpu.cfs_period_us=1000000 cpulimit
$ sudo cgset -r cpu.cfs_quota_us=200000 cpulimit

Run your application:

$ sudo cgexec -g cpu:cpulimit <command>
Glorfindel
  • 815
  • 2
  • 10
  • 19
  • 1
    Thank you! Is it intentional that in the first line you have -g cpu:/cpulimit (with a slash) and in the last line you have -g cpu:cpulimit (without a slash) ? – Johannes Lemonde May 31 '20 at 07:42
1

I'll give you two answers: one that uses cpulimit and an alternate one that makes more sense.

First answer: If you're trying to limit a script with cpulimit, why don't you run the individual tasks inside the script under cpulimit? For instance:

#!/bin/dash
cpulimit --limit 20 -- ~/bin/mprime/mprime -t  # starts a slow mprime

Alternate answer: You're presenting a bit of an x-y problem. You want to give the CPU time to cool off, but you're doing it with a program that works by rapidly suspending and resuming processes.

NOTES
    cpulimit always sends the SIGSTOP and SIGCONT signals to a process,
    both to verify that it can control it  and  to  limit  the  average
    amount  of  CPU it consumes ...

Not only is this an inaccurate kludge that can be replicated with a bash one-liner, but also note that cpulimit messes with the file descriptors in a way that can screw programs up. For instance, had I run mprime in interactive mode with cpulimit --limit 20 -- ~/bin/mprime/mprime in the first example, I would've seen an infinite loop of mprime prompts flood my terminal until I SIGKILLed cpulimit and mprime manually.

Your goal is to give the processor some idle time. The proper way to do this is to downclock the processor so that it spends more time doing nothing. Since the device in question is a Raspberry Pi, this shouldn't be too difficult to accomplish.

P.S.: Rui F Ribeiro is correct in that limiting the processor-intensive task to a single core will help keep temperatures low. It does not make sense to continuously move the process between cores as this will not help the processor cool off in any way since the same amount of power is still being poured into the same chip.