@oaklean/profiler-core
Version:
Part of the @oaklean suite. It provides all basic functions to work with the `.oak` file format. It allows parsing the `.oak` file format as well as tools for analyzing the measurement values. It also provides all necessary capabilities required for prec
143 lines • 11.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CPUModel = void 0;
const CPUNode_1 = require("./CPUNode");
const model_1 = require("../../lib/vscode-js-profile-core/src/cpu/model");
// Types
const types_1 = require("../types");
class CPUModel {
constructor(rootDir, profile, highResolutionBeginTime) {
this.rootDir = rootDir;
this._startTime = profile.startTime;
this._endTime = profile.endTime;
this.cpuModel = (0, model_1.buildModel)(profile);
this._cpuProfilerBeginTime = highResolutionBeginTime;
this._cpuNodes = new Map();
this._profilerHitsPerNode = new Array(this.INodes.length).fill(0);
for (const sampleId of this.cpuModel.samples) {
this._profilerHitsPerNode[sampleId] += 1;
}
}
get profilerHitsPerNode() {
return this._profilerHitsPerNode;
}
set energyValuesPerNode(values) {
if (!values || values.length !== this.INodes.length) {
throw new Error('CPUModel.energyValuesPerNode: node size and energy value size must be the same');
}
this._energyValuesPerNode = values;
}
/**
* energyValuesPerNode is a tuple based array
*
* index 0 of each tuple represents the cpuEnergy
* index 1 of each tuple represents the ramEnergy
*/
get energyValuesPerNode() {
return this._energyValuesPerNode;
}
get ILocations() {
return this.cpuModel.locations;
}
get INodes() {
return this.cpuModel.nodes;
}
get timeDeltas() {
return this.cpuModel.timeDeltas;
}
get samples() {
return this.cpuModel.samples;
}
energyValuesPerNodeByMetricsData(metricsDataCollection) {
/**
* When the measurement begins, the sensor interface starts first,
* and its starting time is stored in (sensorDataBeginTime).
* After a while, the V8 CPU profiler starts, and its start time is stored in (this._highResolutionBeginTime).
*
* The CPU measurements are stored in multiple intervals,
* and all interval lengths are stored in this.timeDeltas[].
*
* this.timeDeltas[]
* | - - - - - - - - - | 0 1 2 3 4 5 6 7 8 9 |
* ^ ^
* | |
* | this._highResolutionBeginTime
* |
* sensorDataBeginTime
*
* The measurements of the sensor interface are also stored as intervals in (metricsDataCollection.items)
*
* metricsDataCollection.items
* | ----- ----- ----- ----- ----- ----- ----|
*
* Each line segment represents the duration of a metricsData object (of metricsDataCollection.items)
*
*/
/**
* energyValuesPerNode is a tuple based array
*
* index 0 of each tuple represents the cpuEnergy
* index 1 of each tuple represents the ramEnergy
*/
const energyValuesPerNode = new Array(this.INodes.length).fill([0, 0]);
const sensorDataBeginTime = metricsDataCollection.items[0].startTime;
let offset = (this._cpuProfilerBeginTime - sensorDataBeginTime)
+ BigInt(this.timeDeltas[0] * 1000);
if (offset < BigInt(0)) {
throw new Error('V8 Profile was measured before the sensor interface began to measure');
}
let currentItemNumber = 0;
let currentMetricsData = metricsDataCollection.items[currentItemNumber];
let energyOfMeasuredProcess = undefined;
for (let i = 1; i < this.timeDeltas.length; i++) {
if (offset > currentMetricsData.duration) {
if (currentItemNumber >= metricsDataCollection.items.length) {
throw new Error('The sensor interface did not measure the whole time the V8 Profiler was running');
}
offset = offset - currentMetricsData.duration;
currentMetricsData = metricsDataCollection.items[++currentItemNumber];
if (currentMetricsData === undefined) {
break;
}
energyOfMeasuredProcess = undefined;
i--; // move one step back to begin at the same timeDelta again but with the next metricsData profile
continue;
}
if (energyOfMeasuredProcess === undefined) {
if (currentMetricsData.processIsPresent(metricsDataCollection.pid)) {
const factor = currentMetricsData.energyPortionOfProcess(metricsDataCollection.pid);
energyOfMeasuredProcess = [
factor * currentMetricsData.cpuEnergy(),
factor * currentMetricsData.ramEnergy(),
];
}
else {
// sometimes outputs of a sensor interface do not include the measured process (e.g. powermetrics)
// It's not clear why this happens, as the PID is present in later reports again.
// one reason could be that the energy usage of the process was negligible and therefore not present
energyOfMeasuredProcess = [
0,
0
];
}
}
energyValuesPerNode[this.samples[i - 1]] = [
(energyOfMeasuredProcess[types_1.EnergyValuesType.CPU] *
(this.timeDeltas[i] / Number(currentMetricsData.duration))),
(energyOfMeasuredProcess[types_1.EnergyValuesType.RAM] *
(this.timeDeltas[i] / Number(currentMetricsData.duration)))
];
offset = offset + BigInt(this.timeDeltas[i] * 1000);
}
return energyValuesPerNode;
}
getNode(index) {
let node = this._cpuNodes.get(index);
if (node === undefined) {
node = new CPUNode_1.CPUNode(index, this, this.rootDir, this.cpuModel.nodes[index]);
}
return node;
}
}
exports.CPUModel = CPUModel;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ1BVTW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaGVscGVyL0NQVU1vZGVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHVDQUFtQztBQUVuQywwRUFBb0g7QUFJcEgsUUFBUTtBQUNSLG9DQUtpQjtBQUVqQixNQUFhLFFBQVE7SUFZcEIsWUFDQyxPQUFvQixFQUNwQixPQUF1QixFQUN2Qix1QkFBMkM7UUFFM0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUE7UUFDdEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFBO1FBQ25DLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQTtRQUMvQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUEsa0JBQVUsRUFBQyxPQUFPLENBQUMsQ0FBQTtRQUNuQyxJQUFJLENBQUMscUJBQXFCLEdBQUcsdUJBQXVCLENBQUE7UUFDcEQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQTtRQUMzQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDakUsS0FBSyxNQUFNLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQzlDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDekMsQ0FBQztJQUNGLENBQUM7SUFFRCxJQUFJLG1CQUFtQjtRQUN0QixPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FBQTtJQUNqQyxDQUFDO0lBRUQsSUFBSSxtQkFBbUIsQ0FBQyxNQUE0RDtRQUNuRixJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVB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