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:
- Determine the process's CPU time between two measurements (t1 and t2)
- Measure the wall-clock time elapsed between t1 and t2
- 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