Linux perf工具未按计数器生成独立结果文件求助
解决Linux perf监控计数器独立文件生成问题
问题重现
尝试用Linux perf工具以500毫秒间隔、10分钟时长监控多个性能计数器,期望每个计数器结果存入独立文件,但实际仅生成一个隐藏的.txt文件,所有结果都写入其中;即使只监控单个计数器,依然无法生成对应结果文件。
问题根源分析
- 计数器名称提取逻辑错误:脚本中用
awk -F"/" '{print $NF}'提取计数器名称,但所有计数器字符串末尾都带有/,导致分割后的最后一个字段为空字符串,最终生成的文件名是perf_results/.txt(隐藏文件)。 - perf命令调用方式冗余:每次循环启动
perf stat并sleep 0.5,不仅效率低下,还可能导致输出格式混乱。
修复后的脚本
#!/bin/bash # 设置监控时长(秒) duration=$((10 * 60)) # 待监控的计数器数组 counters=( "cpu/event=0x00,umask=0x01,name=branch-instructions/" "cpu/event=0x00,umask=0x02,name=branch-misses/" "cpu/event=0x00,umask=0x0e,name=bus-cycles/" "cpu/event=0x00,umask=0x08,name=cache-misses/" "cpu/event=0x00,umask=0x00,name=instructions/" "msr/aperf/" "msr/mperf/" "msr/pperf/" "msr/smi/" "msr/tsc/" "power/energy-cores/" "power/energy-pkg/" "power/energy-ram/" ) # 获取开始时间戳 start_time=$(date +%s) # 创建结果目录 output_dir="perf_results" mkdir -p "$output_dir" # 遍历每个计数器启动监控 for counter in "${counters[@]}"; do # 修正计数器名称提取:先移除末尾的/,再取最后一段 trimmed_counter=$(echo "$counter" | sed 's/\/$//') counter_name=$(echo "$trimmed_counter" | awk -F"/" '{print $NF}') # 处理cpu类计数器的name字段,提取更友好的名称 if [[ "$counter_name" == *"name="* ]]; then counter_name=$(echo "$counter_name" | awk -F"name=" '{print $NF}') fi output_file="${output_dir}/${counter_name}.txt" echo "Starting monitoring for $counter_name, output to $output_file" # 后台运行perf,持续监控直到时长结束,同时记录每次测量的上下文信息 { run=1 # 用perf stat持续输出,每500ms一行,捕获输出并添加额外信息 perf stat -a -e "$counter" -I 500 2>&1 | while read -r line; do current_time=$(date) echo "Run: $run" echo "Time: $current_time" echo "Counter: $counter_name" echo "Measurement: $line" echo ((run++)) done } >> "$output_file" & # 记录后台进程PID,用于到时终止 perf_pids+=("$!") done # 等待指定时长后终止所有perf进程 sleep "$duration" for pid in "${perf_pids[@]}"; do kill "$pid" 2>/dev/null done # 等待所有后台进程退出 wait echo "Monitoring completed. Results stored in $output_dir/"
关键修改说明
- 修正计数器名称提取:
- 先用
sed 's/\/$//'移除计数器字符串末尾的/ - 对CPU类计数器,进一步提取
name=后的友好名称,避免文件名包含event=xxx,umask=xxx,name=前缀
- 先用
- 优化perf运行方式:
- 每个计数器对应一个后台运行的
perf stat进程,持续输出测量结果,避免重复启动进程 - 通过
sleep "$duration"控制总时长,到时自动终止所有perf进程
- 每个计数器对应一个后台运行的
- 增强日志可读性:保留原有的Run、Time、Counter上下文信息,与perf的原始输出结合,便于后续分析
内容的提问来源于stack exchange,提问作者Tre' Jeter
相关产品推荐
相关产品推荐

