diff options
author | Yabin <yabinc@google.com> | 2022-08-18 17:01:54 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2022-08-29 21:25:39 +0000 |
commit | 7fe23bfc69b5dc53a1328ab3afb43fe83eeb3bd3 (patch) | |
tree | c0a7e62448bb710198d1536d74ffc80f7c2fa32f | |
parent | df142880e86418dad6b40fddb001ebd897919595 (diff) | |
download | extras-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.cpp | 27 | ||||
-rw-r--r-- | simpleperf/workload.cpp | 13 | ||||
-rw-r--r-- | simpleperf/workload.h | 1 |
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_; } |