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

Side by Side Diff: base/test/energy_monitor_mac.cc

Issue 1393233002: Mac Energy Test Harness/Framework Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Snapshot of scripts for http://crbug.com/391646 Created 5 years, 2 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 unified diff | Download patch
« no previous file with comments | « base/test/energy_monitor_mac.h ('k') | chrome/browser/ui/cocoa/view_id_util.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/test/energy_monitor_mac.h"
6
7 #include <IntelPowerGadget/EnergyLib.h>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/files/file_util.h"
12 #include "base/logging.h"
13 #include "base/run_loop.h"
14
15 namespace base {
16 namespace test {
17 namespace {
18
19 enum {
20 POWER_DATA_AVERAGE_WATTS = 0,
21 POWER_DATA_CUMULATIVE_JOULES = 1,
22 POWER_DATA_CUMULATIVE_MILLIWATT_HOURS = 2
23 };
24
25 const int kDefaultDelayMs = 50;
26
27 void CheckResult(int result) {
28 CHECK_NE(0, result) << "Intel API call failed.";
29 }
30
31 } // namespace
32
33 EnergyMonitorMac::EnergyMonitorMac()
34 : sample_delay_(base::TimeDelta::FromMilliseconds(kDefaultDelayMs)) {
35 static int initialize_once = IntelEnergyLibInitialize();
36 CHECK_NE(0, initialize_once) << "Failed to initialize.";
37
38 int num_nodes = 0;
39 CheckResult(GetNumNodes(&num_nodes));
40 CHECK_EQ(1, num_nodes) << "Only supports 1 node for now.";
41
42 int num_msrs = 0;
43 CheckResult(GetNumMsrs(&num_msrs));
44
45 for (int msr = 0; msr < num_msrs; ++msr) {
46 int msr_func = 0;
47 CheckResult(GetMsrFunc(msr, &msr_func));
48 if (msr_func != MSR_FUNC_POWER)
49 continue; // Ignore frequency and temperature MSRs.
50
51 char msr_name[4096]; // The API doesn't document a max length for this.
52 CheckResult(GetMsrName(msr, msr_name));
53
54 if (strcmp(msr_name, "IA") == 0) {
55 DCHECK_EQ(-1, samples_[IA].msr_index) << "Multiple IA MSRs";
56 samples_[IA].msr_index = msr;
57 }
58
59 if (strcmp(msr_name, "Processor") == 0) {
60 DCHECK_EQ(-1, samples_[PROCESSOR].msr_index) << "Multiple Processor MSRs";
61 samples_[PROCESSOR].msr_index = msr;
62 }
63 }
64 }
65
66 EnergyMonitorMac::~EnergyMonitorMac() {}
67
68 void EnergyMonitorMac::Run(const base::TimeDelta& warmup_delay,
69 size_t num_samples) {
70 DCHECK_LT(1u, num_samples) << "Need at least 2 samples.";
71 target_sample_count_ = num_samples;
72
73 // First step is to read a sample, but record nothing. This allows
74 // measurements such as watts to establish the first time interval.
75 MessageLoop::current()->PostDelayedTask(
76 FROM_HERE,
77 base::Bind(&EnergyMonitorMac::ReadNextSample, base::Unretained(this)),
78 warmup_delay);
79
80 base::RunLoop run_loop;
81 quit_closure_ = run_loop.QuitClosure();
82 run_loop.Run();
83 }
84
85 void EnergyMonitorMac::SetSampleDelay(const base::TimeDelta& sample_delay) {}
86
87 double EnergyMonitorMac::GetAverageWatts(EnergyType type) const {
88 DCHECK_EQ(target_sample_count_, samples_[type].watts.size());
89 double sum = 0;
90 for (double v : samples_[type].watts)
91 sum += v;
92 return sum / samples_[type].watts.size();
93 }
94
95 double EnergyMonitorMac::GetStdDevWatts(EnergyType type) const {
96 DCHECK_EQ(target_sample_count_, samples_[type].watts.size());
97 const double mean = GetAverageWatts(type);
98 double sum = 0;
99 for (double v : samples_[type].watts) {
100 v -= mean;
101 sum += v * v;
102 }
103 return sqrt(sum / (samples_[type].watts.size() - 1));
104 }
105
106 void EnergyMonitorMac::WriteTimeSeries(const base::FilePath& file) {
107 DCHECK_EQ(target_sample_count_, rdtsc_values_.size());
108 DCHECK_EQ(target_sample_count_, samples_[PROCESSOR].watts.size());
109 DCHECK_EQ(target_sample_count_, samples_[IA].watts.size());
110
111 std::ostringstream csv;
112 csv << "RDTSC,Processor_Watts,IA_Watts\n";
113 for (size_t i = 0; i < rdtsc_values_.size(); ++i) {
114 csv << rdtsc_values_[i] - rdtsc_values_[0]; // Always relative to start.
115 for (int j = 0; j < NUM_ENERGY_TYPES; ++j)
116 csv << ',' << samples_[j].watts[i];
117 csv << '\n';
118 }
119
120 WriteFile(file, csv.str().data(), csv.str().size());
121 }
122
123 void EnergyMonitorMac::ReadNextSample() {
124 CheckResult(ReadSample());
125 if (samples_[0].watts.size() + 1 >= target_sample_count_) {
126 MessageLoop::current()->PostTask(FROM_HERE, quit_closure_);
127 return;
128 }
129 MessageLoop::current()->PostDelayedTask(
130 FROM_HERE,
131 base::Bind(&EnergyMonitorMac::TakeSample, base::Unretained(this)),
132 sample_delay_);
133 }
134
135 void EnergyMonitorMac::TakeSample() {
136 ReadNextSample();
137
138 const int node = 0;
139 for (int i = 0; i < NUM_ENERGY_TYPES; ++i) {
140 int num_data;
141 double data[3];
142
143 CheckResult(GetPowerData(node, samples_[i].msr_index, data, &num_data));
144 DCHECK_EQ(static_cast<int>(arraysize(data)), num_data);
145
146 samples_[i].watts.push_back(data[POWER_DATA_AVERAGE_WATTS]);
147 }
148 uint64_t timestamp;
149 CheckResult(GetRDTSC(&timestamp));
150 rdtsc_values_.push_back(timestamp);
151 }
152
153 } // namespace test
154 } // namespace base
OLDNEW
« no previous file with comments | « base/test/energy_monitor_mac.h ('k') | chrome/browser/ui/cocoa/view_id_util.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698