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 |
24 namespace internal { | |
Alexei Svitkine (slow)
2015/10/13 17:31:19
Nit: Move this below the anon namespace.
dhsharp
2015/10/13 23:36:22
Done.
| |
25 | |
26 // Hopefully we never need a space in a command argument. | |
27 const char* kPerfCommandDelimiter = " "; | |
Alexei Svitkine (slow)
2015/10/13 17:31:19
Nit: const char kPerfCommandDelimiter[] =
(Prefer
dhsharp
2015/10/13 23:36:22
Done.
| |
28 | |
29 const char* kPerfRecordCyclesCmd = | |
Alexei Svitkine (slow)
2015/10/13 17:31:19
These should just be in the anon namespace.
Only
dhsharp
2015/10/13 23:36:22
Done.
| |
30 "perf record -a -e cycles -c 1000003"; | |
31 | |
32 const char* kPerfRecordCallgraphCmd = | |
33 "perf record -a -e cycles -g -c 4000037"; | |
34 | |
35 const char* kPerfRecordLBRCmd = | |
36 "perf record -a -e r2c4 -b -c 20011"; | |
37 | |
38 const char* kPerfRecordInstructionTLBMissesCmd = | |
39 "perf record -a -e iTLB-misses -c 2003"; | |
40 | |
41 const char* kPerfRecordDataTLBMissesCmd = | |
42 "perf record -a -e dTLB-misses -c 2003"; | |
43 | |
44 const char* kPerfStatMemoryBandwidthCmd = | |
45 "perf stat -a -e cycles -e instructions " | |
46 "-e uncore_imc/data_reads/ -e uncore_imc/data_writes/ " | |
47 "-e cpu/event=0xD0,umask=0x11,name=MEM_UOPS_RETIRED-STLB_MISS_LOADS/ " | |
48 "-e cpu/event=0xD0,umask=0x12,name=MEM_UOPS_RETIRED-STLB_MISS_STORES/"; | |
49 | |
50 const std::vector<RandomSelector::WeightAndValue> GetDefaultCommands_x86_64( | |
51 const CPUIdentity& cpuid) { | |
52 using WeightAndValue = RandomSelector::WeightAndValue; | |
Alexei Svitkine (slow)
2015/10/13 17:31:19
Nit: Inline using declarations are not recommended
dhsharp
2015/10/13 23:36:22
This is a type alias, not a using-declaration. It'
Alexei Svitkine (slow)
2015/10/14 15:53:58
Fair enough. Metrics code generally avoids these,
| |
53 std::vector<WeightAndValue> cmds; | |
54 DCHECK(cpuid.arch == "x86_64"); | |
Alexei Svitkine (slow)
2015/10/13 17:31:19
Nit: DCHECK_EQ
Also, please make file-level const
dhsharp
2015/10/13 23:36:22
Done.
Alexei Svitkine (slow)
2015/10/14 15:53:58
Well, my reasoning was that you use it in two plac
| |
55 const std::string intel_uarch = GetIntelUarch(cpuid); | |
56 if (intel_uarch == "IvyBridge" || | |
57 intel_uarch == "Haswell" || | |
58 intel_uarch == "Broadwell") { | |
59 cmds.push_back(WeightAndValue(60.0, kPerfRecordCyclesCmd)); | |
60 cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); | |
61 cmds.push_back(WeightAndValue(5.0, kPerfRecordLBRCmd)); | |
62 cmds.push_back(WeightAndValue(5.0, kPerfRecordInstructionTLBMissesCmd)); | |
63 cmds.push_back(WeightAndValue(5.0, kPerfRecordDataTLBMissesCmd)); | |
64 cmds.push_back(WeightAndValue(5.0, kPerfStatMemoryBandwidthCmd)); | |
65 return cmds; | |
66 } | |
67 if (intel_uarch == "SandyBridge") { | |
68 cmds.push_back(WeightAndValue(65.0, kPerfRecordCyclesCmd)); | |
69 cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); | |
70 cmds.push_back(WeightAndValue(5.0, kPerfRecordLBRCmd)); | |
71 cmds.push_back(WeightAndValue(5.0, kPerfRecordInstructionTLBMissesCmd)); | |
72 cmds.push_back(WeightAndValue(5.0, kPerfRecordDataTLBMissesCmd)); | |
73 return cmds; | |
74 } | |
75 // Other 64-bit x86 | |
76 cmds.push_back(WeightAndValue(70.0, kPerfRecordCyclesCmd)); | |
77 cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); | |
78 cmds.push_back(WeightAndValue(5.0, kPerfRecordInstructionTLBMissesCmd)); | |
79 cmds.push_back(WeightAndValue(5.0, kPerfRecordDataTLBMissesCmd)); | |
80 return cmds; | |
81 } | |
82 | |
83 const std::vector<RandomSelector::WeightAndValue> GetDefaultCommandsForCpu( | |
84 const CPUIdentity& cpuid) { | |
85 using WeightAndValue = RandomSelector::WeightAndValue; | |
86 std::vector<WeightAndValue> cmds; | |
87 if (cpuid.arch == "x86" || // 32-bit x86, or... | |
88 cpuid.arch == "armv7l") { // ARM | |
89 cmds.push_back(WeightAndValue(80.0, kPerfRecordCyclesCmd)); | |
90 cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); | |
91 return cmds; | |
92 } | |
93 if (cpuid.arch == "x86_64") { // 64-bit x86 | |
Alexei Svitkine (slow)
2015/10/13 17:31:19
Nit: No {}'s
dhsharp
2015/10/13 23:36:22
Done.
| |
94 return GetDefaultCommands_x86_64(cpuid); | |
95 } | |
96 // Unknown CPUs | |
97 cmds.push_back(WeightAndValue(1.0, kPerfRecordCyclesCmd)); | |
98 return cmds; | |
99 } | |
100 | |
101 } // namespace internal | |
102 | |
22 namespace { | 103 namespace { |
23 | 104 |
24 // Limit the total size of protobufs that can be cached, so they don't take up | 105 // Limit the total size of protobufs that can be cached, so they don't take up |
25 // too much memory. If the size of cached protobufs exceeds this value, stop | 106 // too much memory. If the size of cached protobufs exceeds this value, stop |
26 // collecting further perf data. The current value is 4 MB. | 107 // collecting further perf data. The current value is 4 MB. |
27 const size_t kCachedPerfDataProtobufSizeThreshold = 4 * 1024 * 1024; | 108 const size_t kCachedPerfDataProtobufSizeThreshold = 4 * 1024 * 1024; |
28 | 109 |
29 // This is used to space out session restore collections in the face of several | 110 // This is used to space out session restore collections in the face of several |
30 // notifications in a short period of time. There should be no less than this | 111 // notifications in a short period of time. There should be no less than this |
31 // much time between collections. | 112 // much time between collections. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after 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(), internal::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 |