Index: tracing/tracing/extras/chrome/cpu_time.html |
diff --git a/tracing/tracing/extras/chrome/cpu_time.html b/tracing/tracing/extras/chrome/cpu_time.html |
index 488f7b86a7aa6e66668484e6e394f16f1c003d6c..742e6323a3d9c3520f3273383a0352d34c9c8ce6 100644 |
--- a/tracing/tracing/extras/chrome/cpu_time.html |
+++ b/tracing/tracing/extras/chrome/cpu_time.html |
@@ -6,6 +6,7 @@ found in the LICENSE file. |
--> |
<link rel="import" href="/tracing/base/multi_dimensional_view.html"> |
+<link rel="import" href="/tracing/extras/chrome/chrome_processes.html"> |
<link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> |
<link rel="import" href="/tracing/model/helpers/chrome_renderer_helper.html"> |
@@ -108,6 +109,18 @@ tr.exportTo('tr.e.chrome.cpuTime', function() { |
} |
/** |
+ * Returns a map of range in |ranges| to total cpu time used by |thread| |
+ * during that range. |
tdresser
2017/04/10 20:48:29
Use jsdoc.
dproy
2017/05/11 00:50:46
Done.
|
+ */ |
+ function computeCpuTimesForRanges_(ranges, thread) { |
+ const rangeToCpuTime = new Map(); |
+ for (const range of ranges) { |
+ rangeToCpuTime.set(range, getCpuTimeForThread(thread, range)); |
+ } |
+ return rangeToCpuTime; |
+ } |
+ |
+ /** |
* Returns a map of segment in |segments| to intersection of bounds of that |
* segment and |rangeOfInterest|. |
* |
@@ -162,10 +175,68 @@ tr.exportTo('tr.e.chrome.cpuTime', function() { |
return stageToInitiatorToRanges; |
} |
+ /** |
+ * Returns the root node of a MultiDimensionalView in TopDownTreeView for cpu |
+ * time. |
+ * |
+ * The returned tree view is three dimensional (processType, threadType, and |
+ * railStage + initiator). Rail stage and initiator are not separate |
+ * dimensions because they are not independent - there is no such thing as CSS |
+ * Response or Scroll Load. |
+ * |
+ * Each node in the tree view contains two values - cpuUsage and cpuTotal. |
+ * |
+ * See cpu_time_multidimensinoal_view.md for more details about the returned |
+ * multidimensional view. |
+ */ |
+ function constructMultiDimensionalView(model, rangeOfInterest) { |
+ const mdvBuilder = new tr.b.MultiDimensionalViewBuilder( |
+ 3 /* dimensions (process, thread and rail stage / initiator) */, |
+ 2 /* valueCount (cpuUsage and cpuTotal) */); |
+ |
+ const stageToInitiatorToRanges = |
+ getStageToInitiatorToSegmentBounds( |
+ model.userModel.segments, rangeOfInterest); |
+ |
+ const allSegmentBoundsInRange = |
+ stageToInitiatorToRanges.get('all_stages').get('all_initiators'); |
+ |
+ for (const pid in model.processes) { |
+ const process = model.processes[pid]; |
+ const processType = |
+ tr.e.chrome.chrome_processes.canonicalizeProcessName(process.name); |
+ for (const tid in process.threads) { |
+ const thread = process.threads[tid]; |
+ const threadType = thread.type; |
+ |
+ // Cache cpuTime for each segment bound. |
+ const rangeToCpuTime = computeCpuTimesForRanges_( |
+ allSegmentBoundsInRange, thread); |
+ |
+ for (const [stage, initiatorToRanges] of stageToInitiatorToRanges) { |
+ for (const [initiator, ranges] of initiatorToRanges) { |
+ const cpuTime = tr.b.math.Statistics.sum(ranges, |
+ range => rangeToCpuTime.get(range)); |
+ const duration = tr.b.math.Statistics.sum(ranges, |
+ range => range.duration); |
+ const cpuTimePerSecond = cpuTime / duration; |
+ mdvBuilder.addPath( |
+ [[processType], [threadType], [stage, initiator]], |
+ [cpuTimePerSecond, cpuTime], |
+ tr.b.MultiDimensionalViewBuilder.ValueKind.TOTAL); |
+ } |
+ } |
+ } |
+ } |
+ |
+ return mdvBuilder.buildTopDownTreeView(); |
+ } |
+ |
return { |
getCpuTimeForThread, |
getStageToInitiatorToSegments, |
getStageToInitiatorToSegmentBounds, |
+ constructMultiDimensionalView, |
}; |
}); |
</script> |