summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2019-07-17 13:23:57 -0700
committerandroid-build-merger <android-build-merger@google.com>2019-07-17 13:23:57 -0700
commit7567476b421b7d7c9f048b73cbb547cb27439e77 (patch)
tree2fc7ca7423494740812b54d34bc395e18baf7c5f
parentbe937770c4ed1396f0497da93c71a7a28876a23f (diff)
parent91f570861c9084fce3df28bbe61a2faeeeb272eb (diff)
downloadextras-7567476b421b7d7c9f048b73cbb547cb27439e77.tar.gz
Merge "simpleperf: add rate comment for new raw events."
am: 91f570861c Change-Id: Ib38fc00f3cb6fdd4eeb9d51dac67c9b856509d71
-rw-r--r--simpleperf/cmd_list.cpp18
-rw-r--r--simpleperf/cmd_stat.cpp94
2 files changed, 82 insertions, 30 deletions
diff --git a/simpleperf/cmd_list.cpp b/simpleperf/cmd_list.cpp
index d9fdf9c8..11b87927 100644
--- a/simpleperf/cmd_list.cpp
+++ b/simpleperf/cmd_list.cpp
@@ -71,11 +71,19 @@ static bool IsEventTypeSupported(const EventType& event_type) {
static void PrintEventTypesOfType(uint32_t type, const std::string& type_name,
const std::set<EventType>& event_types) {
printf("List of %s:\n", type_name.c_str());
- if (type == PERF_TYPE_RAW && (GetBuildArch() == ARCH_ARM || GetBuildArch() == ARCH_ARM64)) {
- printf(" # Please refer to \"PMU common architectural and microarchitectural event numbers\"\n"
- " # and \"ARM recommendations for IMPLEMENTATION DEFINED event numbers\" listed in\n"
- " # ARMv8 manual for details.\n"
- " # A possible link is https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile.\n");
+ if (GetBuildArch() == ARCH_ARM || GetBuildArch() == ARCH_ARM64) {
+ if (type == PERF_TYPE_RAW) {
+ printf(
+ // clang-format off
+" # Please refer to \"PMU common architectural and microarchitectural event numbers\"\n"
+" # and \"ARM recommendations for IMPLEMENTATION DEFINED event numbers\" listed in\n"
+" # ARMv8 manual for details.\n"
+" # A possible link is https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile.\n"
+ // clang-format on
+ );
+ } else if (type == PERF_TYPE_HW_CACHE) {
+ printf(" # More cache events are available in `simpleperf list raw`.\n");
+ }
}
for (auto& event_type : event_types) {
if (event_type.type == type) {
diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp
index 31ab2a39..bc047cb8 100644
--- a/simpleperf/cmd_stat.cpp
+++ b/simpleperf/cmd_stat.cpp
@@ -24,6 +24,7 @@
#include <chrono>
#include <set>
#include <string>
+#include <string_view>
#include <vector>
#include <android-base/file.h>
@@ -128,6 +129,43 @@ struct CounterSummary {
}
};
+static const std::unordered_map<std::string_view, std::pair<std::string_view, std::string_view>>
+ COMMON_EVENT_RATE_MAP = {
+ {"cache-misses", {"cache-references", "miss rate"}},
+ {"branch-misses", {"branch-instructions", "miss rate"}},
+};
+
+static const std::unordered_map<std::string_view, std::pair<std::string_view, std::string_view>>
+ ARM_EVENT_RATE_MAP = {
+ // Refer to "D6.10.5 Meaningful ratios between common microarchitectural events" in ARMv8
+ // specification.
+ {"raw-l1i-cache-refill", {"raw-l1i-cache", "level 1 instruction cache refill rate"}},
+ {"raw-l1i-tlb-refill", {"raw-l1i-tlb", "level 1 instruction TLB refill rate"}},
+ {"raw-l1d-cache-refill", {"raw-l1d-cache", "level 1 data or unified cache refill rate"}},
+ {"raw-l1d-tlb-refill", {"raw-l1d-tlb", "level 1 data or unified TLB refill rate"}},
+ {"raw-l2d-cache-refill", {"raw-l2d-cache", "level 2 data or unified cache refill rate"}},
+ {"raw-l2i-cache-refill", {"raw-l2i-cache", "level 2 instruction cache refill rate"}},
+ {"raw-l3d-cache-refill", {"raw-l3d-cache", "level 3 data or unified cache refill rate"}},
+ {"raw-l2d-tlb-refill", {"raw-l2d-tlb", "level 2 data or unified TLB refill rate"}},
+ {"raw-l2i-tlb-refill", {"raw-l2i-tlb", "level 2 instruction TLB refill rate"}},
+ {"raw-bus-access", {"raw-bus-cycles", "bus accesses per cycle"}},
+ {"raw-ll-cache-miss", {"raw-ll-cache", "last level data or unified cache refill rate"}},
+ {"raw-dtlb-walk", {"raw-l1d-tlb", "data TLB miss rate"}},
+ {"raw-itlb-walk", {"raw-l1i-tlb", "instruction TLB miss rate"}},
+ {"raw-ll-cache-miss-rd", {"raw-ll-cache-rd", "memory read operation miss rate"}},
+ {"raw-remote-access-rd",
+ {"raw-remote-access", "read accesses to another socket in a multi-socket system"}},
+ // Refer to "Table K3-2 Relationship between REFILL events and associated access events" in
+ // ARMv8 specification.
+ {"raw-l1d-cache-refill-rd", {"raw-l1d-cache-rd", "level 1 cache refill rate, read"}},
+ {"raw-l1d-cache-refill-wr", {"raw-l1d-cache-wr", "level 1 cache refill rate, write"}},
+ {"raw-l1d-tlb-refill-rd", {"raw-l1d-tlb-rd", "level 1 TLB refill rate, read"}},
+ {"raw-l1d-tlb-refill-wr", {"raw-l1d-tlb-wr", "level 1 TLB refill rate, write"}},
+ {"raw-l2d-cache-refill-rd", {"raw-l2d-cache-rd", "level 2 data cache refill rate, read"}},
+ {"raw-l2d-cache-refill-wr", {"raw-l2d-cache-wr", "level 2 data cache refill rate, write"}},
+ {"raw-l2d-tlb-refill-rd", {"raw-l2d-tlb-rd", "level 2 data TLB refill rate, read"}},
+};
+
class CounterSummaries {
public:
explicit CounterSummaries(bool csv) : csv_(csv) {}
@@ -231,31 +269,9 @@ class CounterSummaries {
sap_mid);
}
}
- if (android::base::EndsWith(s.type_name, "-misses")) {
- std::string other_name;
- if (s.type_name == "cache-misses") {
- other_name = "cache-references";
- } else if (s.type_name == "branch-misses") {
- other_name = "branch-instructions";
- } else {
- other_name =
- s.type_name.substr(0, s.type_name.size() - strlen("-misses")) + "s";
- }
- const CounterSummary* other = FindSummary(other_name, s.modifier);
- if (other != nullptr && other->IsMonitoredAtTheSameTime(s) &&
- other->count != 0) {
- double miss_rate = static_cast<double>(s.count) / other->count;
- return android::base::StringPrintf("%lf%%%cmiss rate", miss_rate * 100,
- sap_mid);
- }
- }
- if (android::base::EndsWith(s.type_name, "-refill")) {
- std::string other_name = s.type_name.substr(0, s.type_name.size() - strlen("-refill"));
- const CounterSummary* other = FindSummary(other_name, s.modifier);
- if (other != nullptr && other->IsMonitoredAtTheSameTime(s) && other->count != 0) {
- double miss_rate = static_cast<double>(s.count) / other->count;
- return android::base::StringPrintf("%f%%%cmiss rate", miss_rate * 100, sap_mid);
- }
+ std::string rate_comment = GetRateComment(s, sap_mid);
+ if (!rate_comment.empty()) {
+ return rate_comment;
}
double running_time_in_sec;
if (!FindRunningTimeForSummary(s, &running_time_in_sec)) {
@@ -274,6 +290,34 @@ class CounterSummaries {
return android::base::StringPrintf("%.3lf%c/sec", rate, sap_mid);
}
+ std::string GetRateComment(const CounterSummary& s, char sep) {
+ std::string_view miss_event_name = s.type_name;
+ std::string event_name;
+ std::string rate_desc;
+ if (auto it = COMMON_EVENT_RATE_MAP.find(miss_event_name); it != COMMON_EVENT_RATE_MAP.end()) {
+ event_name = it->second.first;
+ rate_desc = it->second.second;
+ }
+ if (event_name.empty() && (GetBuildArch() == ARCH_ARM || GetBuildArch() == ARCH_ARM64)) {
+ if (auto it = ARM_EVENT_RATE_MAP.find(miss_event_name); it != ARM_EVENT_RATE_MAP.end()) {
+ event_name = it->second.first;
+ rate_desc = it->second.second;
+ }
+ }
+ if (event_name.empty() && android::base::ConsumeSuffix(&miss_event_name, "-misses")) {
+ event_name = std::string(miss_event_name) + "s";
+ rate_desc = "miss rate";
+ }
+ if (!event_name.empty()) {
+ const CounterSummary* other = FindSummary(event_name, s.modifier);
+ if (other != nullptr && other->IsMonitoredAtTheSameTime(s) && other->count != 0) {
+ double miss_rate = static_cast<double>(s.count) / other->count;
+ return android::base::StringPrintf("%f%%%c%s", miss_rate * 100, sep, rate_desc.c_str());
+ }
+ }
+ return "";
+ }
+
bool FindRunningTimeForSummary(const CounterSummary& summary, double* running_time_in_sec) {
for (auto& s : summaries_) {
if ((s.type_name == "task-clock" || s.type_name == "cpu-clock") &&