UNPKG

@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
"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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ1BVTW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaGVscGVyL0NQVU1vZGVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHVDQUFtQztBQUVuQywwRUFBb0g7QUFJcEgsUUFBUTtBQUNSLG9DQUtpQjtBQUVqQixNQUFhLFFBQVE7SUFZcEIsWUFDQyxPQUFvQixFQUNwQixPQUF1QixFQUN2Qix1QkFBMkM7UUFFM0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUE7UUFDdEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFBO1FBQ25DLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQTtRQUMvQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUEsa0JBQVUsRUFBQyxPQUFPLENBQUMsQ0FBQTtRQUNuQyxJQUFJLENBQUMscUJBQXFCLEdBQUcsdUJBQXVCLENBQUE7UUFDcEQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQTtRQUMzQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDakUsS0FBSyxNQUFNLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQzlDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDekMsQ0FBQztJQUNGLENBQUM7SUFFRCxJQUFJLG1CQUFtQjtRQUN0QixPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FBQTtJQUNqQyxDQUFDO0lBRUQsSUFBSSxtQkFBbUIsQ0FBQyxNQUE0RDtRQUNuRixJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLGdGQUFnRixDQUFDLENBQUE7UUFDbEcsQ0FBQztRQUNELElBQUksQ0FBQyxvQkFBb0IsR0FBRyxNQUFNLENBQUE7SUFDbkMsQ0FBQztJQUVEOzs7OztXQUtJO0lBQ0osSUFBSSxtQkFBbUI7UUFDdEIsT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQUE7SUFDakMsQ0FBQztJQUVELElBQUksVUFBVTtRQUNiLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUE7SUFDL0IsQ0FBQztJQUVELElBQUksTUFBTTtRQUNULE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUE7SUFDM0IsQ0FBQztJQUVELElBQUksVUFBVTtRQUNiLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFtQyxDQUFBO0lBQ3pELENBQUM7SUFFRCxJQUFJLE9BQU87UUFDVixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFBO0lBQzdCLENBQUM7SUFFRCxnQ0FBZ0MsQ0FBQyxxQkFBNEM7UUFFNUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O1dBdUJHO1FBRUg7Ozs7O1dBS0c7UUFDSCxNQUFNLG1CQUFtQixHQUE2QyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQy9HLE1BQU0sbUJBQW1CLEdBQUcscUJBQXFCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQTtRQUNwRSxJQUFJLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxtQkFBbUIsQ0FBQztjQUM1RCxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQXVCLENBQUE7UUFFMUQsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDeEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxzRUFBc0UsQ0FBQyxDQUFBO1FBQ3hGLENBQUM7UUFFRCxJQUFJLGlCQUFpQixHQUFHLENBQUMsQ0FBQTtRQUN6QixJQUFJLGtCQUFrQixHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO1FBQ3ZFLElBQUksdUJBQXVCLEdBQXVELFNBQVMsQ0FBQTtRQUUzRixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNqRCxJQUFJLE1BQU0sR0FBRyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDMUMsSUFBSSxpQkFBaUIsSUFBSSxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7b0JBQzdELE1BQU0sSUFBSSxLQUFLLENBQUMsaUZBQWlGLENBQUMsQ0FBQTtnQkFDbkcsQ0FBQztnQkFDRCxNQUFNLEdBQUcsTUFBTSxHQUFHLGtCQUFrQixDQUFDLFFBQThCLENBQUE7Z0JBQ25FLGtCQUFrQixHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUE7Z0JBQ3JFLElBQUksa0JBQWtCLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQ3RDLE1BQUs7Z0JBQ04sQ0FBQztnQkFDRCx1QkFBdUIsR0FBRyxTQUFTLENBQUE7Z0JBQ25DLENBQUMsRUFBRSxDQUFBLENBQUMsZ0dBQWdHO2dCQUNwRyxTQUFRO1lBQ1QsQ0FBQztZQUNELElBQUksdUJBQXVCLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzNDLElBQUksa0JBQWtCLENBQUMsZ0JBQWdCLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDcEUsTUFBTSxNQUFNLEdBQUcsa0JBQWtCLENBQUMsc0JBQXNCLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLENBQUE7b0JBQ25GLHVCQUF1QixHQUFHO3dCQUN6QixNQUFNLEdBQUcsa0JBQWtCLENBQUMsU0FBUyxFQUF1Qjt3QkFDNUQsTUFBTSxHQUFHLGtCQUFrQixDQUFDLFNBQVMsRUFBdUI7cUJBQzVELENBQUE7Z0JBQ0YsQ0FBQztxQkFBTSxDQUFDO29CQUNQLGtHQUFrRztvQkFDbEcsaUZBQWlGO29CQUNqRixvR0FBb0c7b0JBQ3BHLHVCQUF1QixHQUFHO3dCQUN6QixDQUFzQjt3QkFDdEIsQ0FBc0I7cUJBQ3RCLENBQUE7Z0JBQ0YsQ0FBQztZQUNGLENBQUM7WUFDRCxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHO2dCQUN4QyxDQUFDLHVCQUF1QixDQUFDLHdCQUFnQixDQUFDLEdBQUcsQ0FBQztvQkFDOUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUNwQztnQkFDdEIsQ0FBQyx1QkFBdUIsQ0FBQyx3QkFBZ0IsQ0FBQyxHQUFHLENBQUM7b0JBQzdDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FDckM7YUFDdEIsQ0FBQTtZQUVELE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUF1QixDQUFBO1FBQzFFLENBQUM7UUFFRCxPQUFPLG1CQUFtQixDQUFBO0lBQzNCLENBQUM7SUFFRCxPQUFPLENBQUMsS0FBYTtRQUNwQixJQUFJLElBQUksR0FBd0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDekQsSUFBSSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDeEIsSUFBSSxHQUFHLElBQUksaUJBQU8sQ0FDakIsS0FBSyxFQUNMLElBQUksRUFDSixJQUFJLENBQUMsT0FBTyxFQUNaLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUMxQixDQUFBO1FBQ0YsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFBO0lBRVosQ0FBQztDQUNEO0FBM0tELDRCQTJLQyJ9