Last active
May 1, 2025 10:48
-
-
Save creotiv/63166cb1c3c6d0e5c14e678542306bdc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Script to monitor CPU throttling time and generate a plot | |
# Auto-install required packages | |
install_python_packages() { | |
for package in "$@"; do | |
if ! python3 -c "import $package" &> /dev/null; then | |
echo "Installing Python package: $package" | |
pip3 install "$package" || pip3 install --break-system-packages "$package" || python3 -m pip install "$package" ||{ | |
echo "Failed to install $package. Please install it manually." | |
exit 1 | |
} | |
fi | |
done | |
} | |
# Check if Python is installed | |
if ! command -v python3 &> /dev/null; then | |
echo "Python 3 is required but not installed. Please install Python 3." | |
exit 1 | |
fi | |
# Auto-install required packages | |
echo "Checking and installing required Python packages..." | |
install_python_packages matplotlib numpy | |
# Create a temporary file for data | |
DATA_FILE=$(mktemp) | |
echo "Timestamp,CPU,ThrottleTime" > "$DATA_FILE" | |
# Function to clean up and create plot | |
cleanup_and_plot() { | |
echo -e "\nCreating plot from collected data..." | |
# Create the plot using Python | |
python3 - "$DATA_FILE" <<EOF | |
import sys | |
import matplotlib.pyplot as plt | |
import numpy as np | |
import csv | |
from datetime import datetime | |
import matplotlib.dates as mdates | |
import os | |
# Read the data file | |
data_file = sys.argv[1] | |
# Detect unique CPUs from the data | |
cpu_ids = set() | |
timestamps = [] | |
csv_data = [] | |
# Parse the CSV file to find all unique CPUs | |
with open(data_file, 'r') as f: | |
reader = csv.reader(f) | |
header = next(reader) # Skip header | |
for row in reader: | |
if len(row) == 3: # Ensure row is valid | |
timestamp_str, cpu, throttle_time = row | |
try: | |
cpu = int(cpu) | |
cpu_ids.add(cpu) | |
csv_data.append((timestamp_str, cpu, throttle_time)) | |
except (ValueError, TypeError): | |
continue | |
# Sort CPUs for consistent colors | |
cpus = sorted(list(cpu_ids)) | |
if not cpus: | |
print("No CPU data found. Exiting.") | |
sys.exit(1) | |
# Initialize data structures | |
cpu_data = {cpu: [] for cpu in cpus} | |
timestamps_dict = {} | |
# Parse the collected data | |
for row in csv_data: | |
timestamp_str, cpu, throttle_time = row | |
try: | |
timestamp = datetime.fromisoformat(timestamp_str) | |
throttle_time = float(throttle_time) | |
if timestamp not in timestamps: | |
timestamps.append(timestamp) | |
cpu_data[cpu].append(throttle_time) | |
except (ValueError, TypeError): | |
continue | |
# Sort timestamps | |
timestamps.sort() | |
# Create the plot | |
plt.figure(figsize=(12, 8)) | |
for cpu in cpus: | |
if cpu_data[cpu]: # Only plot if we have data | |
plt.plot(timestamps[:len(cpu_data[cpu])], cpu_data[cpu], marker='o', linestyle='-', label=f'CPU {cpu}') | |
plt.title('CPU Throttling Time') | |
plt.xlabel('Time') | |
plt.ylabel('Throttle Time (ms)') | |
plt.grid(True) | |
plt.legend() | |
# Format x-axis to show time nicely | |
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S')) | |
plt.gcf().autofmt_xdate() | |
# Save the plot | |
output_file = 'cpu_throttle_data.png' | |
plt.savefig(output_file) | |
print(f"Plot saved as {output_file}") | |
# Also save a copy of the raw data as CSV | |
import shutil | |
shutil.copyfile(data_file, 'cpu_throttle_data.csv') | |
print(f"Raw data saved as cpu_throttle_data.csv") | |
EOF | |
# Clean up temp file | |
rm -f "$DATA_FILE" | |
echo "Done!" | |
exit 0 | |
} | |
# Set trap for Ctrl+C | |
trap cleanup_and_plot SIGINT | |
# Detect number of CPUs | |
NUM_CPUS=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4) | |
echo "Detected $NUM_CPUS CPUs on this system" | |
echo "Monitoring CPU throttling data. Press Ctrl+C to stop and generate plot." | |
echo "Data will be collected every 5 seconds..." | |
# Main loop to collect data | |
while true; do | |
timestamp=$(date -Iseconds) | |
for cpu in $(seq 0 $((NUM_CPUS-1))); do | |
# Get throttle time using sudo | |
throttle_time=$(sudo cat /sys/devices/system/cpu/cpu${cpu}/thermal_throttle/core_throttle_total_time_ms 2>/dev/null || echo "0") | |
# Check if we got a valid number | |
if [[ "$throttle_time" =~ ^[0-9]+$ ]]; then | |
echo "$timestamp,$cpu,$throttle_time" >> "$DATA_FILE" | |
else | |
echo "$timestamp,$cpu,0" >> "$DATA_FILE" | |
fi | |
done | |
# Wait for 5 seconds | |
sleep 5 | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment