noobcoder
noobcoder

Reputation: 6651

Throttle CPU usage of only one thread intentionally

There are a couple of other similar questions on SO, but none of them have satisfactory/relevant answers.

I have a single threaded C++ program which does something essentially like this:

while(true) {
    //do things which are cpu bound
}

The problem is that when I run this program it is usually the only process on my whole computer that is doing active work.

With nothing else to schedule, the OS naturally schedules this program heavily and my CPU usage shoots through the roof, which I do not want. Naturally, my fan starts whirring too which is especially annoying.

The way I am combating this is to add sleep(100) inside the loop (this is fine in terms of correctness for me), but while it works, it annoys me that it's not the technically correct solution.

This is because if I wanted to sleep for a very accurate amount of time and I had lots of other processes running on my computer this would not be a good solution, as sleep is not accurate and it also doesn't allow other processes to use the CPU while my program is still scheduled - but this is not my real problem.

What would be the correct solution to reduce CPU usage without using sleep, assuming this is the only program that is actively running?

Upvotes: 1

Views: 1325

Answers (3)

Jerry Coffin
Jerry Coffin

Reputation: 490098

This is relatively difficult to do from inside your program. Most of the effective methods (at least of which I'm aware) have to be imposed from the outside, so to speak.

On Linux, one possibility is cpulimit, which monitors CPU usage, and pauses your program periodically when necessary to keep its CPU usage down to the level you specify.

Linux does have things like setrlimit and cgroups to control a process' resource usage, but neither of those will work for the scenario you specify (e.g., limiting CPU usage, even when/if the system is otherwise idle). The limits you've been able to set traditionally have been on a process' total CPU usage, rather than the usage rate, so things like setrlimit and rctl are sort of similar, but don't provide quite what you want.

If you're using Windows, you can do this via a Windows Job Object. You create a job object, then set the limits on that job object with SetInformationJobObject using a JOBOBJECT_CPU_RATE_CONTROL_INFORMATION.

Upvotes: 1

Brendan
Brendan

Reputation: 37214

There are 3 cases to consider here.

Polling Loops

For polling loops, the "correct" solution is more like:

while(true) {
    wait_for_something();
    //do things which are cpu bound
}

The problem is deciding what you should be waiting for (time, a key press, a vertical sync signal, a received packet, ....?); and then trying to find something that actually does what you need.

CPU Bound With Terminal Condition

For this case, the "correct" solution would be more like:

do {
    //do things which are cpu bound
} while (running);

In this case you may (should?) set the thread's priority to "very low priority" so that it doesn't interfere with other threads. The OS can decide whether to (or not to) reduce CPU power/speed when there's only low priority threads running; but that's not your decision (it's OS's decision, hopefully with some user/admin power management controls).

CPU Bound Without Terminal Condition

This case is extremely rare (so rare that I can't think of a plausible scenario and I'm not even sure it exists in practice). Mostly if you think your case is "CPU bound without terminal condition" you're probably wrong and it's probably one of the other cases.

If it actually is "CPU bound without terminal condition", then it's mostly just the same as "CPU bound with terminal condition" except there's no condition (you'd still want a low priority thread, and power management when there's only low priority threads running is still not your decision).

Upvotes: 1

blackpen
blackpen

Reputation: 2414

I frequently face similar situation with perl scripts while working with number crunching problems. I put my machine in power savings mode (by putting a max cpu threshold limit) while running these scripts. That helps.

Upvotes: 0

Related Questions