Linux – Among “ps” command output fields, %CPU isn’t the actual CPU usage of the process

command linelinuxps

For example, one of the output fields of this BSD style command, ps aux, is "%CPU". The alternative command, ps -efl outputs the "C" (or CP) field.

As per the ps man page:

  • %CPU is the cpu utilization of the process in "##.#" format. Currently, it is the CPU time used divided by the time the process has been running (cputime/realtime ratio), expressed as a percentage.
  • C is essentially %CPU expressed as an integer

That is how the ps man page details %CPU or C. But most books and websites on the internet simply say, %CPU or C is CPU usage of a process.

One would think that it means % of the CPU's processing power used by a process out of the total available processing power from the CPU. Or is it only me?

Best Answer

The ratio of CPU time to real time (computed in one of the many sensible ways) is the measure of the percent of CPU processing power used by a process out of the total processing power available from the CPU.

Each process in the system can be in two kinds of state: it is either running on a processor or it is waiting (reality is a bit more complex than that and there are more process states, but for the sake of simplicity this answer doesn't differentiate between non-running states, like runnable, interruptible wait, non-interruptible wait etc).

Ordinary process usually spends some time running on a processor and then ends up waiting for an event to happen (e.g. data arriving on a network connection, disk I/O completing, lock becoming available, CPU becoming available again for a runnable process after it has used up its time quantum).

The ratio of the time that a process spends running on a processor in a certain time interval to the length of this interval is a very interesting characteristic. Processes may differ in this characteristic significantly, e.g. a process running scientific computing program will very likely end up using a lot of CPU and little I/O while your shell mostly waits for I/O and does a bit of processing sporadically.

In idealized situation (no overhead from the scheduler, no interrupts etc) and with perfect measurement the sum of CPU time used by each process on a system within one second would be less than one second, the remaining time being the idle CPU time. As you add more processes, especially CPU-bound ones the idle CPU time fraction shrinks and the amount of total CPU time used by all processes within each second approaches one second. At that point addition of extra processes may result in runnable processes waiting for CPU and thus increasing run queues lengths (and hence load averages) and eventually slowing the system down.

Note that taking a simple ratio of process's entire CPU time to the time elapsed since it started ends up representing process's average CPU usage. Since some processes change behavior during runtime (e.g. database server waiting for queries vs the same database server executing a number of complex queries) it is often more interesting to know the most recent CPU usage. For this reason some systems (e.g. FreeBSD, Mac OS X) employ a decaying average as per this manpage:

The CPU utilization of the process; this is a decaying average over up to a minute of previous (real) time. Since the time base over which this is computed varies (since processes may be very young) it is possible for the sum of all %cpu fields to exceed 100%.

Linux has a simplified accounting which gives you CPU usage as per this manpage:

CPU usage is currently expressed as the percentage of time spent running during the entire lifetime of a process. This is not ideal, and it does not conform to the standards that ps otherwise conforms to. CPU usage is unlikely to add up to exactly 100%.