Skip to content

Instantly share code, notes, and snippets.

@paulrouget
Last active April 4, 2016 10:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paulrouget/8a83c6018b7df64f9037b718addea54e to your computer and use it in GitHub Desktop.
Save paulrouget/8a83c6018b7df64f9037b718addea54e to your computer and use it in GitHub Desktop.
plot powermetrics results
var TIME = 30 * 1000;
var SAMPLE_TIME = 500;
const TARGET = "servo";
var exec = require('child_process').exec;
var is_root = process.getuid && process.getuid() === 0;
if (!is_root) {
console.error("Not root");
process.exit(1);
}
var cmd = `powermetrics --samplers tasks --show-process-energy --show-process-gpu -n ${~~(TIME / SAMPLE_TIME)} -i ${SAMPLE_TIME}`;
console.log(cmd);
var before = Date.now();
exec(cmd, {maxBuffer: 1024 * 1024 * 100}, function(error, stdout, stderr) {
console.log(error, stderr);
console.log((Date.now() - before));
console.log("powermetrics done. Parsing…");
onPowerMetricsDone(stdout);
});
console.log(`Tracking ${TARGET} for ${TIME}ms`);
function onPowerMetricsDone(pmOutput) {
// For: sudo powermetrics --samplers tasks --show-process-energy --show-process-gpu -n 50 -i 200 > ~/Desktop/output.txt
// With:
// *** Sampled system activity (Mon Apr 4 09:32:22 2016 +0200) (204.97ms elapsed)
// Name ID CPU ms/s User% Deadlines (<2 ms, 2-5 ms) Wakeups (Intr, Pkg idle) GPU ms/s Energy Impact
// Google Chrome Helper 22141 1.96 53.94 0.00 0.00 4.87 4.87 0.00 0.29"
const FIELDS = [
"ID",
"CPU ms/s",
"User%",
"Deadlines (<2 ms)",
"Deadlines (2-5 ms)",
"Wakeups (Intr, Pkg idle)",
"GPU ms/s",
"Energy Impact",
]
const f = "\\s+(-?\\d*.\\d+)";
const values_format = new RegExp(`(.+[^\\s])${f}${f}${f}${f}${f}${f}${f}${f}${f}`);
const sampled_format = new RegExp(/\*\*\* Sampled system activity \(.*\) \((\d*.\d+)ms elapsed\)/);
var lines = pmOutput.split("\n");
var previous_time = 0;
var samples = [];
var res, sample;
var csv = "";
for (var line of lines) {
sample = samples[samples.length - 1];
if (line == "") {
continue;
}
res = values_format.exec(line);
if (res) {
sample.processes.push({
name: res[1],
fields: res.slice(2),
});
continue;
}
res = sampled_format.exec(line);
if (res) {
var delta = parseFloat(res[1]);
var time = delta + previous_time;
previous_time = time;
// New sample
samples.push({
time: time,
processes: [],
});
continue;
}
}
csv = (["time", ...FIELDS].map(s => `'${s}'`).join(","));
for (var sample of samples) {
var time = sample.time;
var target_process = sample.processes.filter(p => p.name == TARGET);
if (target_process.length == 0) {
continue;
}
if (target_process.length > 1) {
console.error("wut?");
}
csv += ([time, ...target_process[0].fields].join(",")) + "\n";
}
var temp = require('temp');
var fs = require('fs');
temp.track();
temp.open('powermetrics-data-', function(err, info) {
if (!err) {
fs.write(info.fd, csv);
fs.close(info.fd, function(err) {
var plt = `set datafile separator ","
set term png size 1600,800
set output "~/Desktop/a.png"
set xlabel "Time in ms"
set multiplot layout 2, 2
set title "CPU ms/s"
set yrange [0:4000]
plot "${info.path}" using 1:3 notitle with lines
set title "%USER"
set yrange [0:100]
plot "${info.path}" using 1:4 notitle with lines
set title "GPU ms/s"
set yrange [0:1000]
plot "${info.path}" using 1:9 notitle with lines
set title "Energy Impact"
set yrange [0:1000]
plot "${info.path}" using 1:10 notitle with lines
`.split("\n").map(s => s.trim()).join(";");
var gp_cmd = `gnuplot -e '${plt}'`;
console.log(gp_cmd);
exec(gp_cmd, function(error, stdout, stderr) {
console.log(stdout);
console.log(stderr);
});
});
} else {
console.log("Error");
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment