1

Given a VM with 1 CPU. I run two similar CPU intensive tasks in two terminals:

/usr/bin/nice -n -20 perl -e 'while(1){$a=1+1;}'
/usr/bin/nice -n 19 perl -e 'while(1){$a=1+1;}'

I would expect that when I check with top, 1 process would take all the CPU and the other none (because there is no idle time left). But...

  PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
18175 root       1 -20 20376 1460 1132 R  49.9  0.1   0:18.36 perl
18176 root      39  19 20376 1460 1132 R  49.9  0.1   0:15.16 perl   

Why is that? I want my process to humbly only use idle CPU cycles :)

Tested on Linux 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

Willem
  • 2,712
  • 3
  • 27
  • 34
  • Is that "one CPU with hyperthreading"? In that case the higher prio process cannot consume the other one's CPU time if it's single-threaded (as this computation obviously is). Does pressing `I` change this top output to nearly 100%? – Hauke Laging Apr 19 '13 at 19:56
  • It doesn't have ht. However, disabling the autogroup scheduler feature did the trick, see the comment on mdpc's answer. – Willem Apr 20 '13 at 10:01

1 Answers1

3

There is an "art" used in task scheduling. The standard Linux/Unix scheduling algorithm allows all processes at some point to get CPU. This is done by initially, assigning a process two items: (1) lowest priority in its catagory (as determined from its nice) and (2) a time increment again based on priority cateory. As time goes on the process priority gets incremented, the highest priority process gets CPU time. Also, the process getting CPU is continually redetermined from tick to tick based on highest priority at that time after the recalculation. Once a process gets CPU time, its priority returns again to the lowest priority in its catagory.

You could get what you wanted by using "realtime" priorities, where highest priority class processes gets the CPU and gets to use it until all processes in the priority class are satisified, then processes in the next lower class gets the available time, until either a higher priority process requires the CPU, and so on until the total CPU scheduling increment is used up. A process can relinquish part of the CPU increment, thus causing a reschedule.

Thus you are seeing on using the standard scheduler, your lower priority process still getting CPU time but at a far lower rate.

mdpc
  • 11,698
  • 28
  • 51
  • 65
  • 1
    Mostly right, but `This is done by initially, assigning a process two items, (1) lowest priority in its catagory (as determined from its nice) and (2) an time increment again based on priority cateory.` is not quite right, on linux the value with the lowest `se.vruntime` is scheduled to run. This is in `/proc//sched`. Niceness alters how `vruntime` is added to when a task is preempted so as to raise or lower the vruntime actually accumulated whilst the task was running. `nice` actually changes the `weight` value in `/proc//sched` – Matthew Ife Apr 19 '13 at 20:17
  • 1
    Thanks for the explanation about realtime priorities. However I found that `echo 0 > /proc/sys/kernel/sched_autogroup_enabled` also did the trick (from http://serverfault.com/questions/405092/nice-level-not-working-on-linux?rq=1) – Willem Apr 20 '13 at 09:59