Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: tracing/tracing/metrics/system_health/cpu_time_metric.html

Issue 2804043003: [WIP] [DEFINITELY NOT READY TO LAND] Cpu time metric implementation (Closed)
Patch Set: pick up changes from children Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tracing/tracing/metrics/system_health/cpu_time_metric.html
diff --git a/tracing/tracing/metrics/system_health/cpu_time_metric.html b/tracing/tracing/metrics/system_health/cpu_time_metric.html
index abfc457fb58f8e6a795688a8e3ffb317100d9bcd..ba0487938b9ead75959df8540d71b63c78622c45 100644
--- a/tracing/tracing/metrics/system_health/cpu_time_metric.html
+++ b/tracing/tracing/metrics/system_health/cpu_time_metric.html
@@ -9,21 +9,124 @@ found in the LICENSE file.
<link rel="import" href="/tracing/model/helpers/chrome_model_helper.html">
<link rel="import" href="/tracing/model/helpers/chrome_renderer_helper.html">
<link rel="import" href="/tracing/value/histogram.html">
+<link rel="import" href="/tracing/extras/chrome/cpu_time.html">
+
+<!-- Experimental -->
+<link rel="import" href="/tracing/base/multi_dimensional_view.html">
<script>
+// TODO: (Do this before landing) Cleanup imports once you're done
'use strict';
tr.exportTo('tr.metrics.sh', function() {
- // Use a lower bound of 0.01 for the metric boundaries (when no CPU time
- // is consumed) and an upper bound of 50 (fifty cores are all active
- // for the entire time). We can't use zero exactly for the lower bound with an
- // exponential histogram.
- const CPU_TIME_PERCENTAGE_BOUNDARIES =
- tr.v.HistogramBinBoundaries.createExponential(0.01, 50, 200);
+ const CPU_TIME_UNIT = tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;
+ const CPU_TIME_TOTAL_UNIT = tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;
+
+ const cpuTime = tr.e.chrome.cpuTime;
+
+ /**
+ * Translates a multidimensional tree view path to process type, thread type,
+ * rail stage, and initiator type.
+ */
+ function translatePath_(path) {
+ return {
+ processType: path[0][0],
+ threadType: path[1][0],
+ railStage: path[2][0],
+ initiatorType: path[2][1]
+ };
+ }
+
+ function createNewHistogramAndAddSample_(
+ histograms, histogramName, value, unit) {
+ const histogram = new tr.v.Histogram(histogramName, unit);
+ histogram.customizeSummaryOptions({
+ avg: false,
+ count: false,
+ max: false,
+ min: false,
+ std: false,
+ sum: true
+ });
+ histogram.addSample(value);
+ histograms.addHistogram(histogram);
+ }
+
+ function getCanonicalHistogramName_(
+ histogramPrefix, processType, threadType, railStage, initiatorType) {
+ return `${histogramPrefix}:${processType}:${threadType}:` +
+ `${railStage}:${initiatorType}`;
+ }
+
+ function maybeAddDataToHistograms_(histograms, path, node) {
+ const translatedPath = translatePath_(path);
+ const processType = translatedPath.processType || 'all_processes';
+ const threadType = translatedPath.threadType || 'all_threads';
+
+ // We need some rail stage and some initiator type to process a node
+ // All rail stages and all initiator types are handled by the special
+ // 'all_stages' and 'all_initiators' nodes respectively.
+ if (!translatedPath.railStage || !translatedPath.initiatorType) return;
+ const {railStage, initiatorType} = translatedPath;
+
+ const cpuUsageValue = node.values[0].total;
+ const cpuTotalValue = node.values[1].total;
+
+ createNewHistogramAndAddSample_(
+ histograms,
+ getCanonicalHistogramName_(
+ 'cpuUsage', processType, threadType, railStage, initiatorType),
+ cpuUsageValue, CPU_TIME_UNIT);
+
+ createNewHistogramAndAddSample_(
+ histograms,
+ getCanonicalHistogramName_(
+ 'cpuTotal', processType, threadType, railStage, initiatorType),
+ cpuTotalValue, CPU_TIME_TOTAL_UNIT);
+ }
/**
- * This metric measures total CPU time for Chrome processes, per second of
- * clock time.
+ * Returns a string representing which cpu time metric this node represents.
+ * This is not quite the histogram name, but a unique key for the node to
+ * keep track of whether it has been visited.
+ */
+ function getCanonicalTitleFromPath_(path) {
+ const translatedPath = translatePath_(path);
+ const titleComponents =
+ ['processType', 'threadType', 'railStage', 'initiatorType'];
+ return titleComponents.map(key => translatedPath[key]).join(':');
+ }
+
+ function clonePath_(previousPath) {
+ return previousPath.map(subPath => subPath.map(x => x));
+ }
+
+ /**
+ * Traverses all the path of a multidimensional tree view starting from
+ * |node|, creates necessary histograms and adds samples to them.
+ *
+ * TODO: DO BEFORE LANDING: Add param descriptions to this jsdoc.
+ */
+ function reportDataFromTree_(histograms, node, currentPath, visitedSet) {
+ const canonicalTitle = getCanonicalTitleFromPath_(currentPath);
+ if (visitedSet.has(canonicalTitle)) return;
+ visitedSet.add(canonicalTitle);
+ maybeAddDataToHistograms_(histograms, currentPath, node);
+
+ for (let dimension = 0; dimension < node.children.length; dimension++) {
+ const children = node.children[dimension];
+ for (const [name, node] of children) {
+ const newPath = clonePath_(currentPath);
+ newPath[dimension].push(name);
+ reportDataFromTree_(histograms, node, newPath, visitedSet);
+ }
+ }
+ }
+
+ /**
+ * This metric measures total cpuTime utilization per second of wall clock
+ * time.
+ *
* This metric requires only the 'toplevel' tracing category.
*
* @param {!tr.v.HistogramSet} histograms
@@ -31,79 +134,16 @@ tr.exportTo('tr.metrics.sh', function() {
* @param {!Object=} opt_options
*/
function cpuTimeMetric(histograms, model, opt_options) {
- let rangeOfInterest = model.bounds;
-
+ var rangeOfInterest = model.bounds;
if (opt_options && opt_options.rangeOfInterest) {
rangeOfInterest = opt_options.rangeOfInterest;
- } else {
- // If no range of interest is provided, limit the relevant range to
- // Chrome processes. This prevents us from normalizing against non-Chrome
- // related slices in the trace.
- const chromeHelper = model.getOrCreateHelper(
- tr.model.helpers.ChromeModelHelper);
- if (chromeHelper) {
- const chromeBounds = chromeHelper.chromeBounds;
- if (chromeBounds) {
- rangeOfInterest = chromeBounds;
- }
- }
}
- let allProcessCpuTime = 0;
-
- for (const pid in model.processes) {
- const process = model.processes[pid];
- if (tr.model.helpers.ChromeRendererHelper.isTracingProcess(process)) {
- continue;
- }
-
- let processCpuTime = 0;
- for (const tid in process.threads) {
- const thread = process.threads[tid];
- let threadCpuTime = 0;
- thread.sliceGroup.topLevelSlices.forEach(function(slice) {
- if (slice.duration === 0) return;
- if (!slice.cpuDuration) return;
- const sliceRange = tr.b.math.Range.fromExplicitRange(
- slice.start, slice.end);
- const intersection = rangeOfInterest.findIntersection(sliceRange);
- const fractionOfSliceInsideRangeOfInterest =
- intersection.duration / slice.duration;
-
- // We assume that if a slice doesn't lie entirely inside the range of
- // interest, then the CPU time is evenly distributed inside of the
- // slice.
- threadCpuTime +=
- slice.cpuDuration * fractionOfSliceInsideRangeOfInterest;
- });
- processCpuTime += threadCpuTime;
- }
- allProcessCpuTime += processCpuTime;
- }
-
- // Normalize cpu time by clock time.
- let normalizedAllProcessCpuTime = 0;
- if (rangeOfInterest.duration > 0) {
- normalizedAllProcessCpuTime =
- allProcessCpuTime / rangeOfInterest.duration;
- }
-
- const unit = tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;
- const cpuTimeHist = new tr.v.Histogram(
- 'cpu_time_percentage', unit, CPU_TIME_PERCENTAGE_BOUNDARIES);
- cpuTimeHist.description =
- 'Percent CPU utilization, normalized against a single core. Can be ' +
- 'greater than 100% if machine has multiple cores.';
- cpuTimeHist.customizeSummaryOptions({
- avg: true,
- count: false,
- max: false,
- min: false,
- std: false,
- sum: false
- });
- cpuTimeHist.addSample(normalizedAllProcessCpuTime);
- histograms.addHistogram(cpuTimeHist);
+ const treeRoot =
+ cpuTime.constructMultiDimensionalView(model, rangeOfInterest);
+ const rootPath = [[], [], []];
+ const visitedSet = new Set();
+ reportDataFromTree_(histograms, treeRoot, rootPath, visitedSet);
}
tr.metrics.MetricRegistry.register(cpuTimeMetric, {

Powered by Google App Engine
This is Rietveld 408576698