OLD | NEW |
---|---|
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 from metrics import Metric | 5 from metrics import Metric |
6 | 6 |
7 class CpuMetric(Metric): | 7 class CpuMetric(Metric): |
8 """Calulates CPU load over a span of time.""" | 8 """Calulates CPU load over a span of time.""" |
9 | 9 |
10 def __init__(self, browser): | 10 def __init__(self, browser): |
(...skipping 12 matching lines...) Expand all Loading... | |
23 def Stop(self, page, tab): | 23 def Stop(self, page, tab): |
24 assert self._start_cpu, 'Must call Start() first' | 24 assert self._start_cpu, 'Must call Start() first' |
25 self._results = _SubtractCpuStats(self._browser.cpu_stats, self._start_cpu) | 25 self._results = _SubtractCpuStats(self._browser.cpu_stats, self._start_cpu) |
26 | 26 |
27 # Optional argument trace_name is not in base class Metric. | 27 # Optional argument trace_name is not in base class Metric. |
28 # pylint: disable=W0221 | 28 # pylint: disable=W0221 |
29 def AddResults(self, tab, results, trace_name='cpu_utilization'): | 29 def AddResults(self, tab, results, trace_name='cpu_utilization'): |
30 assert self._results, 'Must call Stop() first' | 30 assert self._results, 'Must call Stop() first' |
31 # Add a result for each process type. | 31 # Add a result for each process type. |
32 for process_type in self._results: | 32 for process_type in self._results: |
33 if process_type == 'Global': | |
34 continue | |
33 trace_name_for_process = '%s_%s' % (trace_name, process_type.lower()) | 35 trace_name_for_process = '%s_%s' % (trace_name, process_type.lower()) |
34 cpu_percent = 100 * self._results[process_type] | 36 cpu_percent = 100 * self._results[process_type] |
35 results.Add(trace_name_for_process, '%', cpu_percent, | 37 results.Add(trace_name_for_process, '%', cpu_percent, |
36 chart_name='cpu_utilization', data_type='unimportant') | 38 chart_name='cpu_utilization', data_type='unimportant') |
39 # Add a result for Global CPU stats: these are system-wide metrics, | |
40 # not per process as the ones above. | |
41 total_time = 0.0 | |
42 frequency_sum = 0.0 | |
43 for frequency, time_in_state in \ | |
44 self._results['Global']['GlobalCpuFrequencyStats'].iteritems(): | |
45 frequency_sum += (frequency * time_in_state) | |
46 total_time += time_in_state | |
47 results.Add('average_frequency_hz', 'Hz', | |
qyearsley
2014/04/22 18:22:26
This would require changing a couple places, but m
bulach
2014/04/22 18:34:50
good point! rounded to MHz with 2 digits precision
qyearsley
2014/04/22 18:48:37
I think that sounds good; although note that in or
| |
48 int(frequency_sum / total_time), | |
qyearsley
2014/04/22 18:22:26
Is total_time ever 0.0? (i.e. would it ever be the
bulach
2014/04/22 18:34:50
ahn, great catch, thanks! I'm only adding this to
| |
49 chart_name='cpu_frequency', | |
50 data_type='unimportant') | |
37 | 51 |
38 | 52 |
39 def _SubtractCpuStats(cpu_stats, start_cpu_stats): | 53 def _SubtractCpuStats(cpu_stats, start_cpu_stats): |
40 """Computes average cpu usage over a time period for different process types. | 54 """Computes average cpu usage over a time period for different process types. |
41 | 55 |
42 Each of the two cpu_stats arguments is a dict with the following format: | 56 Each of the two cpu_stats arguments is a dict with the following format: |
43 {'Browser': {'CpuProcessTime': ..., 'TotalTime': ...}, | 57 {'Browser': {'CpuProcessTime': ..., 'TotalTime': ...}, |
44 'Renderer': {'CpuProcessTime': ..., 'TotalTime': ...} | 58 'Renderer': {'CpuProcessTime': ..., 'TotalTime': ...} |
45 'Gpu': {'CpuProcessTime': ..., 'TotalTime': ...}} | 59 'Gpu': {'CpuProcessTime': ..., 'TotalTime': ...}} |
46 | 60 |
47 The 'CpuProcessTime' fields represent the number of seconds of CPU time | 61 The 'CpuProcessTime' fields represent the number of seconds of CPU time |
48 spent in each process, and total time is the number of real seconds | 62 spent in each process, and total time is the number of real seconds |
49 that have passed (this may be a Unix timestamp). | 63 that have passed (this may be a Unix timestamp). |
50 | 64 |
51 Returns: | 65 Returns: |
52 A dict of process type names (Browser, Renderer, etc.) to ratios of cpu | 66 A dict of process type names (Browser, Renderer, etc.) to ratios of cpu |
53 time used to total time elapsed. | 67 time used to total time elapsed. |
54 """ | 68 """ |
55 cpu_usage = {} | 69 cpu_usage = {} |
56 for process_type in cpu_stats: | 70 for process_type in cpu_stats: |
57 assert process_type in start_cpu_stats, 'Mismatching process types' | 71 assert process_type in start_cpu_stats, 'Mismatching process types' |
58 # Skip any process_types that are empty. | 72 # Skip any process_types that are empty. |
59 if (not cpu_stats[process_type]) or (not start_cpu_stats[process_type]): | 73 if ((not cpu_stats[process_type]) or |
74 (not start_cpu_stats[process_type]) or | |
75 process_type == 'Global'): | |
60 continue | 76 continue |
61 cpu_process_time = (cpu_stats[process_type]['CpuProcessTime'] - | 77 cpu_process_time = (cpu_stats[process_type]['CpuProcessTime'] - |
62 start_cpu_stats[process_type]['CpuProcessTime']) | 78 start_cpu_stats[process_type]['CpuProcessTime']) |
63 total_time = (cpu_stats[process_type]['TotalTime'] - | 79 total_time = (cpu_stats[process_type]['TotalTime'] - |
64 start_cpu_stats[process_type]['TotalTime']) | 80 start_cpu_stats[process_type]['TotalTime']) |
65 assert total_time > 0, 'Expected total_time > 0, was: %d' % total_time | 81 assert total_time > 0, 'Expected total_time > 0, was: %d' % total_time |
66 cpu_usage[process_type] = float(cpu_process_time) / total_time | 82 cpu_usage[process_type] = float(cpu_process_time) / total_time |
83 | |
84 if 'Global' not in cpu_stats: | |
85 return cpu_usage | |
86 | |
87 frequency_stats = cpu_stats['Global']['GlobalCpuFrequencyStats'] | |
88 start_frequency_stats = start_cpu_stats['Global']['GlobalCpuFrequencyStats'] | |
89 total_frequency_stats = {} | |
90 for k in frequency_stats.iterkeys(): | |
91 total_frequency_stats[k] = frequency_stats[k] - start_frequency_stats[k] | |
92 | |
93 cpu_usage['Global'] = {} | |
94 cpu_usage['Global']['GlobalCpuFrequencyStats'] = total_frequency_stats | |
67 return cpu_usage | 95 return cpu_usage |
68 | |
OLD | NEW |