OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "chrome/browser/metrics/perf/perf_provider_chromeos.h" | 5 #include "chrome/browser/metrics/perf/perf_provider_chromeos.h" |
6 | 6 |
7 #include <algorithm> | |
7 #include <string> | 8 #include <string> |
8 | 9 |
9 #include "base/bind.h" | 10 #include "base/bind.h" |
10 #include "base/callback.h" | 11 #include "base/callback.h" |
11 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
12 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
13 #include "base/rand_util.h" | 14 #include "base/rand_util.h" |
15 #include "base/strings/string_split.h" | |
14 #include "base/threading/sequenced_worker_pool.h" | 16 #include "base/threading/sequenced_worker_pool.h" |
15 #include "chrome/browser/metrics/perf/windowed_incognito_observer.h" | 17 #include "chrome/browser/metrics/perf/windowed_incognito_observer.h" |
16 #include "chrome/browser/ui/browser_list.h" | 18 #include "chrome/browser/ui/browser_list.h" |
17 #include "chromeos/dbus/dbus_thread_manager.h" | 19 #include "chromeos/dbus/dbus_thread_manager.h" |
18 #include "chromeos/dbus/debug_daemon_client.h" | 20 #include "chromeos/dbus/debug_daemon_client.h" |
19 | 21 |
20 namespace metrics { | 22 namespace metrics { |
21 | 23 |
22 namespace { | 24 namespace { |
23 | 25 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
59 bool IsNormalUserLoggedIn() { | 61 bool IsNormalUserLoggedIn() { |
60 return chromeos::LoginState::Get()->IsUserAuthenticated(); | 62 return chromeos::LoginState::Get()->IsUserAuthenticated(); |
61 } | 63 } |
62 | 64 |
63 // Returns a random TimeDelta between zero and |max|. | 65 // Returns a random TimeDelta between zero and |max|. |
64 base::TimeDelta RandomTimeDelta(base::TimeDelta max) { | 66 base::TimeDelta RandomTimeDelta(base::TimeDelta max) { |
65 return base::TimeDelta::FromMicroseconds( | 67 return base::TimeDelta::FromMicroseconds( |
66 base::RandGenerator(max.InMicroseconds())); | 68 base::RandGenerator(max.InMicroseconds())); |
67 } | 69 } |
68 | 70 |
71 // Hopefully we never need a space in a command argument. | |
72 const char kPerfCommandDelimiter[] = " "; | |
73 | |
74 const char kPerfRecordCyclesCmd[] = | |
75 "perf record -a -e cycles -c 1000003"; | |
76 | |
77 const char kPerfRecordCallgraphCmd[] = | |
78 "perf record -a -e cycles -g -c 4000037"; | |
79 | |
80 const char kPerfRecordLBRCmd[] = | |
81 "perf record -a -e r2c4 -b -c 20011"; | |
82 | |
83 const char kPerfRecordInstructionTLBMissesCmd[] = | |
84 "perf record -a -e iTLB-misses -c 2003"; | |
85 | |
86 const char kPerfRecordDataTLBMissesCmd[] = | |
87 "perf record -a -e dTLB-misses -c 2003"; | |
88 | |
89 const char kPerfStatMemoryBandwidthCmd[] = | |
90 "perf stat -a -e cycles -e instructions " | |
91 "-e uncore_imc/data_reads/ -e uncore_imc/data_writes/ " | |
92 "-e cpu/event=0xD0,umask=0x11,name=MEM_UOPS_RETIRED-STLB_MISS_LOADS/ " | |
93 "-e cpu/event=0xD0,umask=0x12,name=MEM_UOPS_RETIRED-STLB_MISS_STORES/"; | |
94 | |
95 const std::vector<RandomSelector::WeightAndValue> GetDefaultCommands_x86_64( | |
96 const CPUIdentity& cpuid) { | |
97 using WeightAndValue = RandomSelector::WeightAndValue; | |
98 std::vector<WeightAndValue> cmds; | |
99 DCHECK_EQ(cpuid.arch, "x86_64"); | |
100 const std::string intel_uarch = GetIntelUarch(cpuid); | |
101 if (intel_uarch == "IvyBridge" || | |
102 intel_uarch == "Haswell" || | |
103 intel_uarch == "Broadwell") { | |
104 cmds.push_back(WeightAndValue(60.0, kPerfRecordCyclesCmd)); | |
105 cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); | |
106 cmds.push_back(WeightAndValue(5.0, kPerfRecordLBRCmd)); | |
107 cmds.push_back(WeightAndValue(5.0, kPerfRecordInstructionTLBMissesCmd)); | |
108 cmds.push_back(WeightAndValue(5.0, kPerfRecordDataTLBMissesCmd)); | |
109 cmds.push_back(WeightAndValue(5.0, kPerfStatMemoryBandwidthCmd)); | |
110 return cmds; | |
111 } | |
112 if (intel_uarch == "SandyBridge") { | |
113 cmds.push_back(WeightAndValue(65.0, kPerfRecordCyclesCmd)); | |
114 cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); | |
115 cmds.push_back(WeightAndValue(5.0, kPerfRecordLBRCmd)); | |
116 cmds.push_back(WeightAndValue(5.0, kPerfRecordInstructionTLBMissesCmd)); | |
117 cmds.push_back(WeightAndValue(5.0, kPerfRecordDataTLBMissesCmd)); | |
118 return cmds; | |
119 } | |
120 // Other 64-bit x86 | |
121 cmds.push_back(WeightAndValue(70.0, kPerfRecordCyclesCmd)); | |
122 cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); | |
123 cmds.push_back(WeightAndValue(5.0, kPerfRecordInstructionTLBMissesCmd)); | |
124 cmds.push_back(WeightAndValue(5.0, kPerfRecordDataTLBMissesCmd)); | |
125 return cmds; | |
126 } | |
127 | |
69 } // namespace | 128 } // namespace |
70 | 129 |
130 namespace internal { | |
131 | |
132 std::vector<RandomSelector::WeightAndValue> GetDefaultCommandsForCpu( | |
133 const CPUIdentity& cpuid) { | |
134 using WeightAndValue = RandomSelector::WeightAndValue; | |
135 std::vector<WeightAndValue> cmds; | |
136 if (cpuid.arch == "x86" || // 32-bit x86, or... | |
137 cpuid.arch == "armv7l") { // ARM | |
138 cmds.push_back(WeightAndValue(80.0, kPerfRecordCyclesCmd)); | |
139 cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); | |
140 return cmds; | |
141 } | |
142 if (cpuid.arch == "x86_64") // 64-bit x86 | |
Alexei Svitkine (slow)
2015/10/14 15:53:58
Nit: Make this the first check of the function. Th
dhsharp
2015/10/14 18:07:04
Done.
| |
143 return GetDefaultCommands_x86_64(cpuid); | |
144 | |
145 // Unknown CPUs | |
146 cmds.push_back(WeightAndValue(1.0, kPerfRecordCyclesCmd)); | |
147 return cmds; | |
148 } | |
149 | |
150 } // namespace internal | |
151 | |
71 PerfProvider::CollectionParams::CollectionParams( | 152 PerfProvider::CollectionParams::CollectionParams( |
72 base::TimeDelta collection_duration, | 153 base::TimeDelta collection_duration, |
73 base::TimeDelta periodic_interval, | 154 base::TimeDelta periodic_interval, |
74 TriggerParams resume_from_suspend, | 155 TriggerParams resume_from_suspend, |
75 TriggerParams restore_session) | 156 TriggerParams restore_session) |
76 : collection_duration_(collection_duration.ToInternalValue()), | 157 : collection_duration_(collection_duration.ToInternalValue()), |
77 periodic_interval_(periodic_interval.ToInternalValue()), | 158 periodic_interval_(periodic_interval.ToInternalValue()), |
78 resume_from_suspend_(resume_from_suspend), | 159 resume_from_suspend_(resume_from_suspend), |
79 restore_session_(restore_session) { | 160 restore_session_(restore_session) { |
80 } | 161 } |
(...skipping 13 matching lines...) Expand all Loading... | |
94 /* max_collection_delay = */ base::TimeDelta::FromSeconds(5)), | 175 /* max_collection_delay = */ base::TimeDelta::FromSeconds(5)), |
95 /* restore_session = */ PerfProvider::CollectionParams::TriggerParams( | 176 /* restore_session = */ PerfProvider::CollectionParams::TriggerParams( |
96 /* sampling_factor = */ 10, | 177 /* sampling_factor = */ 10, |
97 /* max_collection_delay = */ base::TimeDelta::FromSeconds(10))); | 178 /* max_collection_delay = */ base::TimeDelta::FromSeconds(10))); |
98 | 179 |
99 PerfProvider::PerfProvider() | 180 PerfProvider::PerfProvider() |
100 : collection_params_(kDefaultParameters), | 181 : collection_params_(kDefaultParameters), |
101 login_observer_(this), | 182 login_observer_(this), |
102 next_profiling_interval_start_(base::TimeTicks::Now()), | 183 next_profiling_interval_start_(base::TimeTicks::Now()), |
103 weak_factory_(this) { | 184 weak_factory_(this) { |
185 command_selector_.SetOdds( | |
186 internal::GetDefaultCommandsForCpu(GetCPUIdentity())), | |
187 | |
104 // Register the login observer with LoginState. | 188 // Register the login observer with LoginState. |
105 chromeos::LoginState::Get()->AddObserver(&login_observer_); | 189 chromeos::LoginState::Get()->AddObserver(&login_observer_); |
106 | 190 |
107 // Register as an observer of power manager events. | 191 // Register as an observer of power manager events. |
108 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> | 192 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> |
109 AddObserver(this); | 193 AddObserver(this); |
110 | 194 |
111 // Register as an observer of session restore. | 195 // Register as an observer of session restore. |
112 on_session_restored_callback_subscription_ = | 196 on_session_restored_callback_subscription_ = |
113 SessionRestore::RegisterOnSessionRestoredCallback( | 197 SessionRestore::RegisterOnSessionRestoredCallback( |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 AddToPerfHistogram(INCOGNITO_ACTIVE); | 417 AddToPerfHistogram(INCOGNITO_ACTIVE); |
334 return; | 418 return; |
335 } | 419 } |
336 | 420 |
337 scoped_ptr<WindowedIncognitoObserver> incognito_observer( | 421 scoped_ptr<WindowedIncognitoObserver> incognito_observer( |
338 new WindowedIncognitoObserver); | 422 new WindowedIncognitoObserver); |
339 | 423 |
340 chromeos::DebugDaemonClient* client = | 424 chromeos::DebugDaemonClient* client = |
341 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); | 425 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); |
342 | 426 |
427 std::vector<std::string> command = base::SplitString( | |
428 command_selector_.Select(), kPerfCommandDelimiter, | |
429 base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); | |
343 client->GetPerfOutput( | 430 client->GetPerfOutput( |
344 collection_params_.collection_duration().InSeconds(), | 431 collection_params_.collection_duration().InSeconds(), command, |
345 base::Bind(&PerfProvider::ParseOutputProtoIfValid, | 432 base::Bind(&PerfProvider::ParseOutputProtoIfValid, |
346 weak_factory_.GetWeakPtr(), base::Passed(&incognito_observer), | 433 weak_factory_.GetWeakPtr(), base::Passed(&incognito_observer), |
347 base::Passed(&sampled_profile))); | 434 base::Passed(&sampled_profile))); |
348 } | 435 } |
349 | 436 |
350 void PerfProvider::DoPeriodicCollection() { | 437 void PerfProvider::DoPeriodicCollection() { |
351 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); | 438 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); |
352 sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION); | 439 sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION); |
353 | 440 |
354 CollectIfNecessary(sampled_profile.Pass()); | 441 CollectIfNecessary(sampled_profile.Pass()); |
(...skipping 18 matching lines...) Expand all Loading... | |
373 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); | 460 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); |
374 sampled_profile->set_trigger_event(SampledProfile::RESTORE_SESSION); | 461 sampled_profile->set_trigger_event(SampledProfile::RESTORE_SESSION); |
375 sampled_profile->set_ms_after_restore(time_after_restore.InMilliseconds()); | 462 sampled_profile->set_ms_after_restore(time_after_restore.InMilliseconds()); |
376 sampled_profile->set_num_tabs_restored(num_tabs_restored); | 463 sampled_profile->set_num_tabs_restored(num_tabs_restored); |
377 | 464 |
378 CollectIfNecessary(sampled_profile.Pass()); | 465 CollectIfNecessary(sampled_profile.Pass()); |
379 last_session_restore_collection_time_ = base::TimeTicks::Now(); | 466 last_session_restore_collection_time_ = base::TimeTicks::Now(); |
380 } | 467 } |
381 | 468 |
382 } // namespace metrics | 469 } // namespace metrics |
OLD | NEW |