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