Understanding CPU Time vs CPU Usage: Calculating Processor Utilization Metrics in Linux Systems


1 views

When examining process statistics in Linux systems through tools like top or htop, understanding the distinction between CPU time and CPU usage is crucial for performance monitoring. CPU time represents the absolute duration a process has actively used the CPU, while CPU usage expresses this as a percentage of total available processing capacity.

Consider this top output example:

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
18118 user      20   0 9248400 261528  78676 S 217.2  0.1   8:14.75 MATLAB

The 217.2% CPU value indicates MATLAB is utilizing approximately 2.17 CPU cores simultaneously. This percentage-based measurement becomes particularly meaningful in multi-core systems where processes can leverage parallel processing.

To manually calculate CPU usage for a process:

  1. Determine the process's CPU time between two measurements (t1 and t2)
  2. Measure the wall-clock time elapsed between t1 and t2
  3. Account for the number of available CPU cores

The formula becomes:

usage_percentage = (cpu_time_delta / wall_time_delta) * 100 * num_cores

Here's a Python script that calculates CPU usage for a given process:

import time
import psutil

def get_cpu_usage(pid, interval=1):
    process = psutil.Process(pid)
    cpu_count = psutil.cpu_count()
    
    # First measurement
    t1 = time.time()
    cpu_t1 = process.cpu_times().user + process.cpu_times().system
    
    time.sleep(interval)
    
    # Second measurement
    t2 = time.time()
    cpu_t2 = process.cpu_times().user + process.cpu_times().system
    
    # Calculate usage
    wall_time = t2 - t1
    cpu_time = cpu_t2 - cpu_t1
    usage = (cpu_time / wall_time) * 100 * cpu_count
    
    return usage

Several factors influence CPU usage calculations:

  • Hyperthreading can make logical cores appear as physical cores
  • CPU frequency scaling affects actual processing capacity
  • Kernel scheduling decisions impact time allocation

Values exceeding 100% indicate multi-threaded processes utilizing multiple cores. For example:

  • 125% = Process using 1.25 cores effectively
  • 400% = Process fully utilizing 4 cores

Understanding these metrics helps in capacity planning, performance tuning, and identifying resource bottlenecks in production systems.


CPU time represents the actual duration a process spends executing on the CPU, typically measured in clock ticks or seconds. CPU usage, however, expresses this duration as a percentage of the CPU's total capacity during a given time window.

When you see a value like 217.2% in top, it indicates MATLAB is using approximately 2.17 CPU cores fully. On multi-core systems, percentages can exceed 100% because each core contributes 100% capacity.

Here's how you can calculate CPU usage for a process in Linux using Python:

import time

def get_cpu_usage(pid, interval=1):
    def get_cpu_time():
        with open(f'/proc/{pid}/stat') as f:
            stats = f.read().split()
        return sum(map(float, stats[13:17]))
    
    t1 = get_cpu_time()
    time.sleep(interval)
    t2 = get_cpu_time()
    
    clock_ticks = os.sysconf(os.sysconf_names['SC_CLK_TCK'])
    return 100 * (t2 - t1) / (clock_ticks * interval)

print(f"CPU Usage: {get_cpu_usage(18118):.1f}%")

The formula breaks down as:

CPU Usage % = (ΔCPU Time / (Clock Ticks × Time Interval)) × 100

Where ΔCPU Time is the change in process CPU time between measurements, and clock ticks per second is typically 100 on Linux systems.

Here's a more robust implementation that handles multiple processes:

import os
import time

def monitor_processes(pids, interval=1, duration=10):
    start_times = {}
    for pid in pids:
        try:
            with open(f'/proc/{pid}/stat') as f:
                stats = f.read().split()
            start_times[pid] = sum(map(float, stats[13:17]))
        except:
            start_times[pid] = 0
    
    time.sleep(interval)
    
    results = {}
    for pid in pids:
        try:
            with open(f'/proc/{pid}/stat') as f:
                stats = f.read().split()
            end_time = sum(map(float, stats[13:17]))
            usage = 100 * (end_time - start_times[pid]) / (os.sysconf('SC_CLK_TCK') * interval)
            results[pid] = usage
        except:
            results[pid] = 0
    
    return results
  • CPU time measures absolute execution duration
  • CPU usage represents relative utilization of CPU capacity
  • Multi-core systems can show >100% usage
  • Accurate measurement requires sampling over time intervals