summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin <yabinc@google.com>2022-08-18 17:01:54 -0700
committerYabin Cui <yabinc@google.com>2022-08-29 21:25:39 +0000
commit7fe23bfc69b5dc53a1328ab3afb43fe83eeb3bd3 (patch)
treec0a7e62448bb710198d1536d74ffc80f7c2fa32f
parentdf142880e86418dad6b40fddb001ebd897919595 (diff)
downloadextras-7fe23bfc69b5dc53a1328ab3afb43fe83eeb3bd3.tar.gz
simpleperf: update --print-hw-counter to check each cpu.
Little/Big cores may have different numbers of CPU PMU hardware counters. So check them separately. Bug: 243479304 Bug: 243034569 Test: run simpleperf_unit_test Change-Id: I33527d69bc935b8523482feaf98378c5f6641762 (cherry picked from commit 6b771a2e12740f4bbcef515d772e62b364d87858)
-rw-r--r--simpleperf/cmd_stat.cpp27
-rw-r--r--simpleperf/workload.cpp13
-rw-r--r--simpleperf/workload.h1
3 files changed, 33 insertions, 8 deletions
diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp
index 40a6bb0b..c46bd548 100644
--- a/simpleperf/cmd_stat.cpp
+++ b/simpleperf/cmd_stat.cpp
@@ -739,23 +739,23 @@ bool StatCommand::ParseOptions(const std::vector<std::string>& args,
return true;
}
-bool StatCommand::PrintHardwareCounters() {
+std::optional<size_t> GetHardwareCountersOnCpu(int cpu) {
size_t available_counters = 0;
const EventType* event = FindEventTypeByName("cpu-cycles", true);
if (event == nullptr) {
- return false;
+ return std::nullopt;
}
perf_event_attr attr = CreateDefaultPerfEventAttr(*event);
while (true) {
auto workload = Workload::CreateWorkload({"sleep", "0.1"});
- if (!workload) {
- return false;
+ if (!workload || !workload->SetCpuAffinity(cpu)) {
+ return std::nullopt;
}
std::vector<std::unique_ptr<EventFd>> event_fds;
for (size_t i = 0; i <= available_counters; i++) {
EventFd* group_event_fd = event_fds.empty() ? nullptr : event_fds[0].get();
- auto event_fd =
- EventFd::OpenEventFile(attr, workload->GetPid(), -1, group_event_fd, "cpu-cycles", false);
+ auto event_fd = EventFd::OpenEventFile(attr, workload->GetPid(), cpu, group_event_fd,
+ "cpu-cycles", false);
if (!event_fd) {
break;
}
@@ -771,7 +771,7 @@ bool StatCommand::PrintHardwareCounters() {
for (auto& event_fd : event_fds) {
PerfCounter counter;
if (!event_fd->ReadCounter(&counter)) {
- return false;
+ return std::nullopt;
}
if (counter.time_enabled == 0 || counter.time_enabled > counter.time_running) {
always_running = false;
@@ -783,7 +783,18 @@ bool StatCommand::PrintHardwareCounters() {
}
available_counters++;
}
- printf("There are %zu CPU PMU hardware counters available on this device.\n", available_counters);
+ return available_counters;
+}
+
+bool StatCommand::PrintHardwareCounters() {
+ for (int cpu : GetOnlineCpus()) {
+ std::optional<size_t> counters = GetHardwareCountersOnCpu(cpu);
+ if (!counters) {
+ LOG(ERROR) << "failed to get CPU PMU hardware counters on cpu " << cpu;
+ return false;
+ }
+ printf("There are %zu CPU PMU hardware counters available on cpu %d.\n", counters.value(), cpu);
+ }
return true;
}
diff --git a/simpleperf/workload.cpp b/simpleperf/workload.cpp
index 4bb7c540..142ed713 100644
--- a/simpleperf/workload.cpp
+++ b/simpleperf/workload.cpp
@@ -18,6 +18,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <sched.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <unistd.h>
@@ -160,6 +161,18 @@ void Workload::ChildProcessFn(int start_signal_fd, int exec_child_fd) {
}
}
+bool Workload::SetCpuAffinity(int cpu) {
+ CHECK_EQ(work_state_, NotYetStartNewProcess);
+ cpu_set_t mask;
+ CPU_ZERO(&mask);
+ CPU_SET(cpu, &mask);
+ if (sched_setaffinity(GetPid(), sizeof(mask), &mask) != 0) {
+ PLOG(ERROR) << "sched_setaffinity failed";
+ return false;
+ }
+ return true;
+}
+
bool Workload::Start() {
CHECK_EQ(work_state_, NotYetStartNewProcess);
char start_signal = 1;
diff --git a/simpleperf/workload.h b/simpleperf/workload.h
index 2400ac8f..86b28924 100644
--- a/simpleperf/workload.h
+++ b/simpleperf/workload.h
@@ -43,6 +43,7 @@ class Workload {
~Workload();
+ bool SetCpuAffinity(int cpu);
bool Start();
bool IsStarted() { return work_state_ == Started; }
pid_t GetPid() { return work_pid_; }