diff --git a/src/vt/metrics/perf_data.cc b/src/vt/metrics/perf_data.cc index 7a0f0db7be..fa3c90709e 100644 --- a/src/vt/metrics/perf_data.cc +++ b/src/vt/metrics/perf_data.cc @@ -74,58 +74,49 @@ PerfData::PerfData() vtAbort("Event name isn't in known perf events map: " + event_name); } } -} -PerfData::~PerfData() -{ - for (auto& [task, fds] : task_fds_map_) + // Initialize perf events once and store file descriptors + for (const auto &event_name : event_names_) { - for (int fd : fds) + struct perf_event_attr pe = {}; + pe.type = event_map_.at(event_name).first; + pe.size = sizeof(struct perf_event_attr); + pe.config = event_map_.at(event_name).second; + + pe.disabled = 1; + pe.exclude_kernel = 1; + pe.exclude_hv = 1; + pe.inherit = 1; // Ensure event is inherited by threads + + if (event_name == "instructions") { + pe.pinned = 1; + } + + int fd = perf_event_open(&pe, 0, -1, -1, PERF_FLAG_FD_CLOEXEC); + if (fd == -1) { - if (fd != -1) - { - close(fd); - } + cleanupBeforeAbort(); + vtAbort("Error opening perf event: " + std::string(strerror(errno))); } + + event_fds_.push_back(fd); } } -void PerfData::startTaskMeasurement(runnable::RunnableNew* task) +PerfData::~PerfData() { - // fmt::print("*********** startTaskMeasurement: PerfData currently is tracking {} tasks\n", task_fds_map_.size()); - if (task_fds_map_.find(task) == task_fds_map_.end()) + for (int fd : event_fds_) { - // fmt::print(" Task was not in the task_fds_map_.\n"); - std::vector fds; - for (const auto &event_name : event_names_) + if (fd != -1) { - struct perf_event_attr pe = {}; - pe.type = event_map_.at(event_name).first; - pe.size = sizeof(struct perf_event_attr); - pe.config = event_map_.at(event_name).second; - - pe.disabled = 1; - pe.exclude_kernel = 1; - pe.exclude_hv = 1; - pe.inherit = 1; // Ensure event is inherited by threads - - if (event_name == "instructions") { - pe.pinned = 1; - } - - int fd = perf_event_open(&pe, 0, -1, -1, PERF_FLAG_FD_CLOEXEC); - if (fd == -1) - { - cleanupBeforeAbort(); - vtAbort("Error opening perf event: " + std::string(strerror(errno))); - } - - fds.push_back(fd); + close(fd); } - task_fds_map_[task] = fds; } +} - for (int fd : task_fds_map_[task]) +void PerfData::startTaskMeasurement(runnable::RunnableNew* task) +{ + for (int fd : event_fds_) { if (fd != -1) { ioctl(fd, PERF_EVENT_IOC_RESET, 0); @@ -136,33 +127,25 @@ void PerfData::startTaskMeasurement(runnable::RunnableNew* task) void PerfData::stopTaskMeasurement(runnable::RunnableNew* task) { - // fmt::print("*********** stopTaskMeasurement: PerfData currently is tracking {} tasks\n", task_fds_map_.size()); - if (task_fds_map_.find(task) != task_fds_map_.end()) + for (int fd : event_fds_) { - for (int fd : task_fds_map_[task]) - { - if (fd != -1) { - ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); - } + if (fd != -1) { + ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); } } } std::unordered_map PerfData::getTaskMeasurements(runnable::RunnableNew* task) { - // fmt::print("*********** getTaskMeasurements: PerfData currently is tracking {} tasks\n", task_fds_map_.size()); std::unordered_map measurements; - if (task_fds_map_.find(task) != task_fds_map_.end()) + for (size_t i = 0; i < event_fds_.size(); ++i) { - for (size_t i = 0; i < task_fds_map_[task].size(); ++i) - { - uint64_t count; - if (task_fds_map_[task][i] != -1 && read(task_fds_map_[task][i], &count, sizeof(uint64_t)) != -1) { - measurements[event_names_[i]] = count; - } - else { - vtWarn("Failed to read perf event data for: " + event_names_[i]); - } + uint64_t count; + if (event_fds_[i] != -1 && read(event_fds_[i], &count, sizeof(uint64_t)) != -1) { + measurements[event_names_[i]] = count; + } + else { + vtWarn("Failed to read perf event data for: " + event_names_[i]); } } return measurements; @@ -170,17 +153,7 @@ std::unordered_map PerfData::getTaskMeasurements(runnable void PerfData::purgeTask(runnable::RunnableNew* task) { - if (task_fds_map_.find(task) != task_fds_map_.end()) - { - for (int fd : task_fds_map_[task]) - { - if (fd != -1) - { - close(fd); - } - } - task_fds_map_.erase(task); - } + // No longer needed since we don't track tasks individually } std::unordered_map> PerfData::getEventMap() const { return event_map_; } @@ -196,17 +169,14 @@ void PerfData::serialize(SerializerT& s) { void PerfData::cleanupBeforeAbort() { - for (auto& [task, fds] : task_fds_map_) + for (int fd : event_fds_) { - for (int fd : fds) + if (fd != -1) { - if (fd != -1) - { - close(fd); - } + close(fd); } } - task_fds_map_.clear(); + event_fds_.clear(); } long PerfData::perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags) diff --git a/src/vt/metrics/perf_data.h b/src/vt/metrics/perf_data.h index c12313aa66..c3658f8915 100644 --- a/src/vt/metrics/perf_data.h +++ b/src/vt/metrics/perf_data.h @@ -89,8 +89,8 @@ struct PerfData: runtime::component::Component private: std::unordered_map> event_map_; - std::unordered_map> task_fds_map_; std::vector event_names_; + std::vector event_fds_; void cleanupBeforeAbort(); static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags);