You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux perf工具未按计数器生成独立结果文件求助

解决Linux perf监控计数器独立文件生成问题

问题重现

尝试用Linux perf工具以500毫秒间隔、10分钟时长监控多个性能计数器,期望每个计数器结果存入独立文件,但实际仅生成一个隐藏的.txt文件,所有结果都写入其中;即使只监控单个计数器,依然无法生成对应结果文件。

问题根源分析

  1. 计数器名称提取逻辑错误:脚本中用awk -F"/" '{print $NF}'提取计数器名称,但所有计数器字符串末尾都带有/,导致分割后的最后一个字段为空字符串,最终生成的文件名是perf_results/.txt(隐藏文件)。
  2. 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/"

关键修改说明

  1. 修正计数器名称提取:
    • 先用sed 's/\/$//'移除计数器字符串末尾的/
    • 对CPU类计数器,进一步提取name=后的友好名称,避免文件名包含event=xxx,umask=xxx,name=前缀
  2. 优化perf运行方式:
    • 每个计数器对应一个后台运行的perf stat进程,持续输出测量结果,避免重复启动进程
    • 通过sleep "$duration"控制总时长,到时自动终止所有perf进程
  3. 增强日志可读性:保留原有的Run、Time、Counter上下文信息,与perf的原始输出结合,便于后续分析

内容的提问来源于stack exchange,提问作者Tre' Jeter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 08:50:18