From 4a60eb0b1b90825e874c5fb60bd4b2e8f8285dea Mon Sep 17 00:00:00 2001 From: l00822163 Date: Mon, 11 Mar 2024 16:37:14 +0800 Subject: [PATCH] Add sum aggregation feature for cycles event. Previously, PMU event counts per line/function are aggregated by MAX operation since some PMU events such as cache miss count requires an estimation of operand count for memory access while SUM operation without the number of operands on that line cannot render an average expression for operand count. However, when we use the number of cycles to evaluate the importance of a function, we can directly add up cycles within the function. --- instruction_map.cc | 19 +++++++++++++++---- profile.cc | 10 +++++++++- symbol_map.cc | 3 +++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/instruction_map.cc b/instruction_map.cc index f460d67..768ab35 100644 --- a/instruction_map.cc +++ b/instruction_map.cc @@ -38,11 +38,22 @@ void InstructionMap::BuildPerFunctionInstructionMap( addr2line_->GetInlineStack(addr, &info->source_stack); inst_map_.insert(InstMap::value_type(addr, info)); if (info->source_stack.size() > 0) { - symbol_map_->AddSourceCount(name, info->source_stack, 0, 1, - SymbolMap::MAX, std::string(), is_repeat); - for (const auto& event_name : symbol_map_->GetProcessingEventName()) { + if (symbol_map_->GetProcessingEventName().empty()) { + // For perf sampling with single PMU event, even if we collect "cycles" + // info, we will not change operation from "MAX" to "SUM". symbol_map_->AddSourceCount(name, info->source_stack, 0, 1, - SymbolMap::MAX, event_name, is_repeat); + SymbolMap::MAX, std::string(), is_repeat); + } else { + for (const auto& event_name : symbol_map_->GetProcessingEventName()) { + SymbolMap::Operation op = SymbolMap::MAX; + if (event_name.find("cycles") == 0) { + // When we collect "cycles" info by perf, switch aggregation + // operation from "MAX" to "SUM". + op = SymbolMap::SUM; + } + symbol_map_->AddSourceCount(name, info->source_stack, 0, 1, + op, event_name, is_repeat); + } } } } diff --git a/profile.cc b/profile.cc index a306562..e563c5e 100644 --- a/profile.cc +++ b/profile.cc @@ -146,10 +146,16 @@ void Profile::ProcessPerFunctionProfile(string func_name, continue; } if (info->source_stack.size() > 0) { + SymbolMap::Operation op = SymbolMap::MAX; + if (event_address.first.find("cycles") == 0) { + // When we collect "cycles" info by perf, switch aggregation + // operation from "MAX" to "SUM". + op = SymbolMap::SUM; + } symbol_map_->AddSourceCount( func_name, info->source_stack, address_count.second * info->source_stack[0].DuplicationFactor(), 0, - SymbolMap::MAX, event_address.first, is_repeat); + op, event_address.first, is_repeat); } } } @@ -165,6 +171,8 @@ void Profile::ProcessPerFunctionProfile(string func_name, continue; } if (info->source_stack.size() > 0) { + // For perf sampling with single PMU event, even if we collect "cycles" + // info, we will not change operation from "MAX" to "SUM". symbol_map_->AddSourceCount( func_name, info->source_stack, address_count.second * info->source_stack[0].DuplicationFactor(), 0, diff --git a/symbol_map.cc b/symbol_map.cc index 233bbb2..322439f 100644 --- a/symbol_map.cc +++ b/symbol_map.cc @@ -398,6 +398,9 @@ void SymbolMap::AddSourceCount(const string &symbol_name, } } else if (op == SUM) { symbol->pos_counts[offset].count += count; + if (!event_name.empty()) { + symbol->event_pos_counts[event_name][offset].count += count; + } } else { LOG(FATAL) << "op not supported."; } -- 2.33.0