Chromium Code Reviews| 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 |