16

I'm looking for a way to occupy exactly 80% (or any other number) of a single CPU in a consistent manner.
I need this for some unit test that tests a component that triggers under specific CPU utilization conditions
For this purpose I can assume that the machine is otherwise idle.

What's a robust and possibly OS independent way to do this?

shoosh
  • 76,898
  • 55
  • 205
  • 325
  • 1
    sounds more like a load test to me; have you looked for any load testing frameworks? – Paul Aug 28 '11 at 16:44
  • Note that some OSes (e.g. Windows) would show 25% load on a quad core machine with one single-threaded process running in an infinite loop. 25% of the total time across all cores being used. So for future readers looking at CPU usage percent, be sure to take that into account when figuring out what you mean by "80%", whether that's of all cores or of one core. – Peter Cordes Mar 22 '23 at 17:02

3 Answers3

17

There is no such thing as occupying the CPU 80% of the time. The CPU is always either being used, or idle. Over some period of time, you can get average usage to be 80%. Is there a specific time period you want it to be averaged over? This pseudo-code should work across platforms and over 1 second have a CPU usage of 80%:

while True:
    startTime = time.now()
    while date.now() - startTime < 0.8:
        Math.factorial(100) // Or any other computation here
    time.sleep(0.2)
Andrew C
  • 3,560
  • 1
  • 23
  • 24
  • so the system call to sleep, and also the call to factorial (a recursive function I guess) have no time cost? – George Kastrinis Aug 28 '11 at 16:51
  • 3
    This is also known as duty-cycle control, or pulse-width modulation. Switch the CPU on for 80% of the time, and off for 20% of the time. With small enough granularity, you'll get '80% utilization'. I would also suggest the OP test their component with more variable loads (e.g. code up a process that uses the above technique for 10% load, then run 8 of them). That way you get a bit more randomness that more likely emulates read conditions. – vsekhar Aug 28 '11 at 16:52
  • @George: The answers and the vsekhar comment are right. What you want it to do is get it spending 20% of its time sleeping, and the other 80% computing something or anything that is CPU-bound. The CPU cost of calling the factorial or sleep functions is relatively very small, but nevertheless you want it to be part of that 80%. – Mike Dunlavey Aug 29 '11 at 01:33
  • it there are multiply CPU cores and logic processors in this machine? how to make every CPU 80% uage? – meadlai Nov 04 '20 at 02:37
5

Its pretty easy to write a program that alternately spins and sleeps to get any particular load level you want. I threw this together in a couple of minutes:

#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

#define INTERVAL    500000
volatile sig_atomic_t   flag;
void setflag(int sig) { flag = 1; }

int main(int ac, char **av) {
    int load = 80;
    struct sigaction sigact;
    struct itimerval interval = { { 0, INTERVAL }, { 0, INTERVAL } };
    struct timespec pausetime = { 0, 0 };
    memset(&sigact, 0, sizeof(sigact));
    sigact.sa_handler = setflag;
    sigaction(SIGALRM, &sigact, 0);
    setitimer(ITIMER_REAL, &interval, 0);
    if (ac == 2) load = atoi(av[1]);
    pausetime.tv_nsec = INTERVAL*(100 - load)*10;
    while (1) {
        flag = 0;
        nanosleep(&pausetime, 0);
        while (!flag) { /* spin */ } }
    return 0;
}
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
3

The trick is that if you want to occupy 80% of CPU, keep the processor busy for 0.8 seconds (or 80% of any time interval. Here I take it to be 1 second), then let it sleep for 0.2 seconds, though it is advisable not to utilize the CPU too much, or all your processes will start running slow. You could try around 20% or so. Here is an example done in Python:

import time
import math
time_of_run = 0.1
percent_cpu = 80 # Should ideally replace this with a smaller number e.g. 20
cpu_time_utilisation = float(percent_cpu)/100
on_time = time_of_run * cpu_time_utilisation
off_time = time_of_run * (1-cpu_time_utilisation)
while True:
    start_time = time.clock()
    while time.clock() - start_time < on_time:
        math.factorial(100) #Do any computation here
    time.sleep(off_time)
Parth
  • 1,114
  • 3
  • 16
  • 25