From 60ad08a465aae2a1648055ab711eb6b91252c8ca Mon Sep 17 00:00:00 2001 From: twwang <920347125@qq.com> Date: Mon, 16 Jun 2025 19:13:19 +0800 Subject: [PATCH] =?UTF-8?q?PmuRead=E5=87=BD=E6=95=B0=E6=80=A7=E8=83=BD?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 8 ++++++++ pmu/pmu_list.cpp | 32 ++++++++++++++++++-------------- pmu/sample_process.cpp | 27 --------------------------- pmu/sample_process.h | 27 ++++++++++++++++++++++++++- pmu/sampler.cpp | 5 +++-- util/common.cpp | 6 ------ util/common.h | 7 ++++++- 7 files changed, 61 insertions(+), 51 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a96e848..f013847 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,14 @@ endif() set(TOP_DIR ${PROJECT_SOURCE_DIR}) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -funroll-loops -fno-plt") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -funroll-loops -fno-plt ") + +if (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^(arm|aarch64)") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8.2-a") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8.2-a") +endif() + message("TOP_DIR is ${TOP_DIR}") include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake) add_subdirectory(symbol) diff --git a/pmu/pmu_list.cpp b/pmu/pmu_list.cpp index 071b924..8ea83ac 100644 --- a/pmu/pmu_list.cpp +++ b/pmu/pmu_list.cpp @@ -15,6 +15,7 @@ ******************************************************************************/ #include #include +#include #include #include "linked_list.h" #include "cpu_map.h" @@ -297,24 +298,27 @@ namespace KUNPENG_PMU { void SortTwoVector(std::vector& pmuData, std::vector& sampleIps) { - std::vector> combined; - combined.reserve(pmuData.size()); - for (size_t i = 0; i < pmuData.size(); ++i) { - combined.emplace_back(std::make_pair(std::move(pmuData[i]), std::move(sampleIps[i]))); - } - - std::sort(combined.begin(), combined.end(), - [](std::pair& a, std::pair& b) { - if (a.first.tid == b.first.tid) { - return a.first.ts < b.first.ts; + std::vector indices(pmuData.size()); + std::iota(indices.begin(), indices.end(), 0); + std::stable_sort(indices.begin(), indices.end(), [&pmuData](size_t a, size_t b){ + if (pmuData[a].tid == pmuData[b].tid) { + return pmuData[a].ts < pmuData[b].ts; } - return a.first.tid < b.first.tid; + return pmuData[a].tid < pmuData[b].tid; }); - for (size_t i = 0; i < pmuData.size(); ++i) { - pmuData[i] = std::move(combined[i].first); - sampleIps[i] = std::move(combined[i].second); + std::vector sortedPmuData; + std::vector sortedSampleIps; + size_t size = pmuData.size(); + sortedPmuData.reserve(size); + sortedSampleIps.reserve(size); + + for (size_t i = 0; i < size; ++i) { + sortedPmuData.emplace_back(std::move(pmuData[indices[i]])); + sortedSampleIps.emplace_back(std::move(sampleIps[indices[i]])); } + pmuData = std::move(sortedPmuData); + sampleIps = std::move(sortedSampleIps); } void HandleBlockData(std::vector& pmuData, std::vector& sampleIps, diff --git a/pmu/sample_process.cpp b/pmu/sample_process.cpp index 778b622..5f30eb6 100644 --- a/pmu/sample_process.cpp +++ b/pmu/sample_process.cpp @@ -22,33 +22,6 @@ #define PAGE_SIZE (sysconf(_SC_PAGESIZE)) #define MB() asm volatile("dmb ish" ::: "memory") static constexpr int MAX_DATA_SIZE = 8192; -#ifdef IS_X86 -#define PerfRingbufferSmpStoreRelease(p, v) \ - ({ \ - union { \ - typeof(*p) val; \ - char charHead[1]; \ - } pointerUnion = {.val = (v)}; \ - asm volatile("mov %1, %0" : "=Q"(*p) : "r"(*(__u64 *)pointerUnion.charHead) : "memory"); \ - }) -#else -#define PerfRingbufferSmpStoreRelease(p, v) \ - ({ \ - union { \ - typeof(*p) val; \ - char charHead[1]; \ - } pointerUnion = {.val = (v)}; \ - asm volatile("stlr %1, %0" : "=Q"(*p) : "r"(*(__u64 *)pointerUnion.charHead) : "memory"); \ - }) -#endif - -void KUNPENG_PMU::PerfMmapConsume(PerfMmap &map) -{ - - __u64 prev = map.prev; - struct perf_event_mmap_page *base = (struct perf_event_mmap_page *)map.base; - PerfRingbufferSmpStoreRelease(&base->data_tail, prev); -} void KUNPENG_PMU::PerfMmapReadDone(PerfMmap &map) { diff --git a/pmu/sample_process.h b/pmu/sample_process.h index 8ad9407..e309c87 100644 --- a/pmu/sample_process.h +++ b/pmu/sample_process.h @@ -18,12 +18,37 @@ #include #include "pmu_event.h" +#ifdef IS_X86 +#define PerfRingbufferSmpStoreRelease(p, v) \ + ({ \ + union { \ + typeof(*p) val; \ + char charHead[1]; \ + } pointerUnion = {.val = (v)}; \ + asm volatile("mov %1, %0" : "=Q"(*p) : "r"(*(__u64 *)pointerUnion.charHead) : "memory"); \ + }) +#else +#define PerfRingbufferSmpStoreRelease(p, v) \ + ({ \ + union { \ + typeof(*p) val; \ + char charHead[1]; \ + } pointerUnion = {.val = (v)}; \ + asm volatile("stlr %1, %0" : "=Q"(*p) : "r"(*(__u64 *)pointerUnion.charHead) : "memory"); \ + }) +#endif + namespace KUNPENG_PMU { int MmapInit(PerfMmap& sampleMmap); union PerfEvent* ReadEvent(PerfMmap& map); int RingbufferReadInit(PerfMmap& map); - void PerfMmapConsume(PerfMmap& map); + inline void PerfMmapConsume(PerfMmap& map) + { + __u64 prev = map.prev; + struct perf_event_mmap_page *base = (struct perf_event_mmap_page *)map.base; + PerfRingbufferSmpStoreRelease(&base->data_tail, prev); + } void PerfMmapReadDone(PerfMmap& map); } // namespace KUNPENG_PMU diff --git a/pmu/sampler.cpp b/pmu/sampler.cpp index 3255aac..aa23978 100644 --- a/pmu/sampler.cpp +++ b/pmu/sampler.cpp @@ -229,8 +229,9 @@ void KUNPENG_PMU::PerfSampler::RawSampleProcess( } } else { for (int i = sample->nr - 1; i >= 0; --i) { - if (IsValidIp(sample->ips[i])) { - ips->ips.emplace_back(sample->ips[i]); + const auto& ip = sample->ips[i]; + if (IsValidIp(ip)) { + ips->ips.emplace_back(ip); } } } diff --git a/util/common.cpp b/util/common.cpp index 67c4a66..c157a5a 100644 --- a/util/common.cpp +++ b/util/common.cpp @@ -28,12 +28,6 @@ #include "pcerr.h" #include "common.h" -bool IsValidIp(unsigned long ip) { - return (ip != PERF_CONTEXT_HV && ip != PERF_CONTEXT_KERNEL && ip != PERF_CONTEXT_USER - && ip != PERF_CONTEXT_GUEST && ip != PERF_CONTEXT_GUEST_KERNEL - && ip != PERF_CONTEXT_GUEST_USER && ip != PERF_CONTEXT_MAX); -} - std::string GetRealPath(const std::string filePath) { char resolvedPath[PATH_MAX]; diff --git a/util/common.h b/util/common.h index 77b8a9b..caa52a3 100644 --- a/util/common.h +++ b/util/common.h @@ -31,7 +31,12 @@ const std::string TRACE_EVENT_PATH = "/sys/kernel/tracing/events/"; const std::string TRACE_DEBUG_EVENT_PATH = "/sys/kernel/debug/tracing/events/"; -bool IsValidIp(unsigned long ip); +inline bool IsValidIp(unsigned long ip) +{ + return (ip != PERF_CONTEXT_HV && ip != PERF_CONTEXT_KERNEL && ip != PERF_CONTEXT_USER + && ip != PERF_CONTEXT_GUEST && ip != PERF_CONTEXT_GUEST_KERNEL + && ip != PERF_CONTEXT_GUEST_USER && ip != PERF_CONTEXT_MAX); +} std::string GetRealPath(const std::string filePath); bool IsValidPath(const std::string& filePath); bool IsDirectory(const std::string& path); -- Gitee