对trace文件的分析

网络上有不少awk程序是讲如何分析网络性能的(主要是时延,吞吐量,丢包率和时延抖动),但是都没有详细的说明,我在此作一些示例,添加了一些必要的说明注释。

以下的内容是针对NS2仿真的结果trace文件进行网络性能分析,看本篇前需要先行了解的的内容有:awk语言的基础,包括语法和结构等;在Linux下如何使用xgraph和gnuplot。

因为只是想简单介绍如何用gwak和xgraph/gnuplot处理trace文件得出分析结果,所以并没有写专门的tcl脚本,分析用的tcl脚本和trace文件是一个三节点的无线网络的例子,随篇附后。

本篇主要想介绍如何得到网络的数据传输延迟(delay)、丢包率(drop)、延时抖动(Jitter)和网络的吞吐量(throughtput),下文的四个awk程序所使用的模型主要来自《網路模擬軟體NS2來做網路效能分析需看的文章》一文,除了第四个外程序没有做很大的改动,只是对封包的处理有所不同,同时第一个程序增加了比较详细的注释,方便初学者学习。因为只是想抛砖引玉,所以分析用的数学模型没有刻意去研究,有待大家一起讨论。

一,延时分析。包的延时就是指包的接收时间与包的发送时间差。下面给出awk程序,相关的说明看程序里面的注释。

#BEGIN表明这是程序开头执行的一段语句,且只执行一次。

BEGIN {

#程序初始化,设定一变量以记录目前处理的封包的最大ID号码。在awk环境下变量的使用不需要声明,直接赋值。

highest_uid = 0;

}

#下面大括号里面的内容会针对要进行处理的记录(也就是我们的trace文件)的每一行都重复执行一次

{

event = $1; #$1表示一行的第一栏,是事件的动作。每一栏默认是以空格分隔的。下同。

time = $2; #事件发生的时间

node_nb = $3; #发生事件的节点号(但是两边夹着“_”,下面一句代码将“_”处理掉)

node_nb=substr(node_nb,2,1); #第三栏的内容是形如_0_的节点号码,我只要得出中间的节点号码0,所以要对字符串_0_进行处理。

trace_type = $4; #trace文件跟踪事件的层次(指在路由层或mac层等等)

flag = $5; #

uid = $6; #包的uid号码(普通包头的uid)

pkt_type = $7; #包的类型(是信令或是数据)

pkt_size = $8; #包的大小(byte)

#下面的代码记录目前最高的CBR流的packet ID,本来的延迟分析是针对所有的包的(包括信令),这里作了简化,只针对CBR封包,以后大家做延时分析可以做相应的改动即可。

if ( event=="s" &&node_nb==0 && pkt_type=="cbr" && uid > highest_uid)

{#if判断句的前三个判断条件就不说了,第四个是说每个包的记录次数不超过1

highest_uid = uid;

}

#记录封包的传送时间

if ( event=="s" &&node_nb==0 && pkt_type=="cbr" && uid==highest_uid )

start_time[uid] = time; # start_time[]表明这是一个数组

#记录封包的接收时间

if ( event=="r" &&node_nb ==2 && pkt_type=="cbr" && uid==highest_uid )

end_time[uid] = time;

}

#END表明这是程序结束前执行的语句,也只执行一次

END {

#当每行资料都读取完毕后,开始计算有效封包的端到端延迟时间。

for ( packet_id = 0; packet_id <=highest_uid; packet_id++ )

{

start = start_time[packet_id];

end = end_time[packet_id];

packet_duration = end - start;

#只把接收时间大于传送时间的记录打印出来

if ( start < end ) printf("%d%f\n", packet_id, packet_duration);

}

}

要注意的是上面的awk程序只是在一个层上进行处理的(我是用的mac层),在生成trace文件时把其他层关闭,只留一个层,否则判断条件要多加一个层的判断。下面的其他三个程序也是一样的。

程序写好以后用一个文档保存为pkt_delay和trace文件放于同一文件夹下,然后在终端进入该文件夹,执行:

$:gwak –f delay trace > p

然后在文件p中就保存了两列数据:封包的序号和该封包的传送时间。

二,丢包率分析。

BEGIN {

#程序初始化,设定变量记录传输以及被丢弃的包的数目

fsDrops = 0; #被丢弃的包的数目

numfs0 = 0; #0节点发送的CBR封包的数目

numfs2 = 0; #2节点接收的CBR封包的数目

}

{

event = $1;

time = $2;

node_nb = $3;

trace_type = $4;

flag = $5;

uid = $6

pkt_type = $7;

pkt_size = $8;

node_nb=substr(node_nb,2,1);

#统计节点0发送的CBR封包

if (node_nb==0 && event=="s" && trace_type== "MAC" && pkt_type=="cbr")

numfs0++;

#统计节点2丢弃的CBR封包

if (node_nb==2 && event=="r" && trace_type== "MAC" && pkt_type=="cbr")

numfs2++;

}

END {

average=0; #average用于记录丢包率

fsDrops = numfs0-numfs2; #丢包数目

average=fsDrops/numfs0; #丢包率

printf("number of packets sent:%dlost_rate:%d\n", numfs0, average); #打印发送封包数目和丢包率

}

程序写好以后用一个文档保存为drop和trace文件放于同一文件夹下,然后在终端进入该文件夹,执行:

$:gwak –f drop trace > d

文件d中记录了两个数据:发送封包数目和丢包率。

三,延时抖动分析

在这里特别提一下,所用的延时抖动分析的模型是:(封包n2的延时-封包n1的延时)/(n2的包序号-n1的包序号)。

BEGIN {

#程序初始化,设定一变量以记录目前处理过的最高封包序号。

highest_uid = 0;

}

{

event = $1;

time = $2;

node_nb = $3;

node_nb=substr(node_nb,2,1);

trace_type = $4;

flag = $5;

uid = $6

pkt_type = $7;

pkt_size = $8;

#记录目前最高的CBR封包的ID

if ( event=="s" &&node_nb==0 && pkt_type=="cbr" && uid > highest_uid)

{

highest_uid = uid;

}

#记录CBR封包的发送时间

if ( event=="s" &&node_nb==0 && pkt_type=="cbr" && uid==highest_uid )

start_time[uid] = time;

#记录CBR封包的接收时间

if ( event=="r" &&node_nb ==2 && pkt_type=="cbr" && uid==highest_uid )

end_time[uid] = time;

}

END {

# 初始化抖动延时所需的变量

last_seqno = 0;

last_delay = 0;

seqno_diff = 0;

#当资料行全部读取后,开始计算有效封包的端到端延迟时间

for ( packet_id = 0; packet_id <=highest_uid; packet_id++ )

{

start = start_time[packet_id];

end = end_time[packet_id];

packet_duration =end - start;

#只把接收时间大于发送时间的记录列出来

if ( start < end )

{

# 得到了delay值(packet_duration)后计算jitter

seqno_diff = packet_id - last_seqno;

delay_diff = packet_duration - last_delay;

if (seqno_diff == 0)

{

jitter =0;

}

else

{

jitter = delay_diff/seqno_diff;

}

#将有效封包序号以及延时抖动打印出来

printf("%d %f\n", packet_id,jitter);

last_seqno = packet_id;

last_delay = packet_duration;

}

}

}

程序写好以后用一个文档保存为jitter和trace文件放于同一文件夹下,然后在终端进入该文件夹,执行:

$:gwak –f jitter trace > j

文件j中记录了有效封包序号以及延时抖动的情况。

四,网络吞吐量分析

网络的吞吐量是网络性能的一个重要参数,是指在不丢包的情况下单位时间内通过的数据包数量,单位是字节每秒或比特每秒。计算其吞吐量是一件复杂的事情,这里的模型是从第一个包发送后,每个包都叠加累算。可能模型不够精准,只是大概的反映,目的只是想让大家了解如何写awk的网络吞吐量分析程序。大家切勿借用本模型在要发表的论文上做分析。

BEGIN {

init=0;

i=0;

}

{

event = $1;

time = $2;

node_nb = $3;

node_nb=substr(node_nb,2,1);

trace_type = $4;

flag = $5;

uid = $6

pkt_type = $7;

pkt_size = $8;

if(event=="r" &&node_nb==2 && pkt_type=="cbr" )

{

pkt_byte_sum[i+1]=pkt_byte_sum+ pkt_size;

if(init==0)

{

start_time = time;

init = 1;

}

end_time = time;

i = i+1;

}

}

END {

#为了画图方便,把第一笔记录的throughput设为零,以表示传输开始

printf("%.2f\t%.2f\n", end_time[0],0);

for(j=1 ; j<i ; j++)

{

th = pkt_byte_sum[j] / (end_time[j] -start_time)*8/1000;

printf("%.2f\t%.2f\n",end_time[j], th);

}

#看图方便,把最后一笔记录的throughput设置为零,以表示传输

printf("%.2f\t%.2f\n",end_time[i-1], 0);

}

程序写好以后用一个文档保存为throughtput和trace文件放于同一文件夹下,然后在终端进入该文件夹,执行:

$:gwak –f throughtput trace> t

文件t中记录了包的接收时间以及吞吐量的情况。

接下来,就是对已经分析得到的结果用图描绘出来。可以用xgraph或者gnuplot。这种绘图工具可以将两列数据中的第一列作横轴,第二列作纵轴用曲线描绘出来。若把数据文件名保存为file,则用xgraph绘图的指令是$:xgraph file;用gnuplot绘图的指令是$:gnuplot,进入gnuplot环境后,可以设置标题,横轴和纵轴的label等:

>set title “titlename”

>set xlabel “xlabelname”

>set ylabel “ylabelname”

然后绘图:

>plot “file” with lines(用连线方式,gnuplot有九种绘图方式)

下面用gnuplot描绘延时,延时抖动以及吞吐量的图形:

1, 包的延时:

>set title “pkt_delay-pkt_id”

>set xlabel “packet_id”

>set ylabel “packet_delay”

>plot “p” with lines

2, 延时抖动:

>set title “jitter-packet”

>set xlabel “packet_id”

>set ylabel “jitter”

>plot “j” with lines

3, 吞吐量:

>set title “throughtput-time”

>set xlabel “time”

>set ylabel “throughtput”

>plot “t” with lines

最后需要说明的是:直接拷贝粘贴word文档内的awk程序编译时一般是通不过的,里面有很多空格键需要去掉,相关的格式对齐用Tab键,否则这些格式问题在Linux下会像小虫一样令你头痛不已。

<think>嗯,用户现在询问的是Perfetto工具的使用方法和操作流程,特别是关于系统性能分析和追踪的操作指南。用户之前的问题是关于高通相机启动流程的,现在突然转向性能分析工具,可能是遇到了相机启动性能优化的问题,想用Perfetto进行诊断。 从用户提供的引用内容看,Perfetto确实是个强大的工具,但用户可能更需要实操指导而非概念介绍。用户引用的资料里包含了Perfetto的核心功能、记录技术、命令行用法等关键信息,特别是引用[5]给出了具体的adb命令示例,这应该作为重点展开。 考虑到用户可能是Android开发者或系统工程师,需要从基础到进阶的完整指引。回复应该覆盖:环境准备(包括Android设备配置)、三种常用追踪方式(UI/命令行/API)、核心分析场景(系统资源、应用行为、相机专项)、以及结果解读技巧。相机专项分析要结合用户之前询问的QCOM相机流程,给出具体trace配置建议。 用户没有明确说分析相机问题,但根据上下文关联性,在"专项场景分析"部分特别加入相机启动追踪是必要的。引用[1][3][4]提到的Trace Processor和SQL分析功能也要重点说明,因为这是Perfetto区别于简单性能监控工具的核心优势。 最后生成的"相关问题"要引导用户深入使用Perfetto,比如针对相机启动延迟的分析方法,这既能解决潜在需求,又能和用户历史问题形成知识闭环。</think>以下是Perfetto工具的完整使用指南,涵盖系统性能分析和追踪操作全流程,结合Android平台实践: --- ### **一、环境准备** 1. **设备要求**: - Android 10+ 设备(完整功能需Android 12+) - 开发者选项开启: ```bash adb shell settings put global settings_enable_tracing 1 # 启用系统级追踪[^5] ``` - 对于非root设备,需授权: ```bash adb shell pm grant android.permission.PERFETTO_USE_USERBUILD_TRACING android.permission.READ_LOGS ``` 2. **工具安装**: - **Perfetto UI**:直接访问 [https://ui.perfetto.dev](https://ui.perfetto.dev)(无需安装) - **命令行工具**: ```bash # 下载预编译二进制 curl -LO https://get.perfetto.dev/tracebox chmod +x tracebox ``` --- ### **二、三种追踪方式** #### **1. Web UI可视化记录(推荐)** - 打开 [https://ui.perfetto.dev](https://ui.perfetto.dev) → 点击"Record new trace" - 配置参数: - **设备连接**:通过ADB连接设备 - **数据源**: - CPU调度:`sched/sched_switch` - GPU频率:`gpu_frequency` - 内存:`memory` - 相机:`camera`(需Android 12+)[^5] - **采样时长**:建议10-30秒 - 点击"Start Recording"开始捕获 #### **2. ADB命令行记录** ```bash adb shell perfetto -o /data/misc/perfetto-traces/trace.perfetto-trace \ --config - <<EOF buffers: { size_kb: 10240 } data_sources: { config { name: "linux.process_stats" target_buffer: 0 } } duration_ms: 10000 # 捕获10秒 EOF ``` - 导出数据: ```bash adb pull /data/misc/perfetto-traces/trace.perfetto-trace ``` #### **3. 代码埋点(App级追踪)** ```java // 在应用代码中插入追踪点 import android.os.Trace; void cameraOpen() { Trace.beginSection("camera_launch"); // 相机初始化代码 Trace.endSection(); } ``` --- ### **三、核心分析场景** #### **1. 系统资源分析** - **CPU调度**: - 查看线程状态:`Running`/`Runnable`/`Sleeping` - 定位卡顿:长时间`Uninterruptible Sleep`(D状态) - **内存分析**: - `meminfo`数据源 → 分析PSS/RSS占用 - OOM诊断:`lowmemorykiller`事件 - **GPU/显示性能**: - `gfx`数据源 → 帧生命周期(App/VSYNC/SurfaceFlinger) - 掉帧检测:`FrameMissed`事件 #### **2. 相机专项分析 ```bash adb shell perfetto --txt -c - -o /data/trace <<EOF data_sources: { config { name: "android.camera" # 相机事件流 } } data_sources: { config { name: "linux.sys_stats" sys_stats_config { meminfo_period_ms: 1000 } } } EOF ``` - 关键追踪点: - `camx`:高通HAL层操作 - `camera_session`:会话生命周期 - `ISP_Frame`:图像处理器耗时 #### **3. SQL高级分析 ```sql SELECT slice.name, COUNT(*), AVG(dur/1e6) AS avg_ms FROM slice WHERE name LIKE 'cam%' GROUP BY name ORDER BY avg_ms DESC; ``` - 常用数据表: | 表名 | 用途 | |---------------|-----------------------| | `slice` | 时间区间事件 | | `process` | 进程信息 | | `thread` | 线程信息 | | `counter` | 数值型指标(如CPU频率)| --- ### **四、结果解读技巧** 1. **时间线视图**: - 缩放:`W`/`S`键 - 选择区域:`Shift + 鼠标拖动` 2. **统计面板**: - 点击事件 → 查看**Duration**直方图 - 右键事件 → `Run metric`生成性能报告 3. **相机启动优化示例: - 定位瓶颈:`camera_open` > 100ms → 检查HAL日志 - 分析流水线:并行化`ISP_init`和`sensor_config` --- ### **五、最佳实践** 1. **轻量级配置**: ```protobuf # 最小化配置(仅CPU/内存) buffers: { size_kb: 2048 } data_sources: { config { name: "linux.sys_stats" } } ``` 2. **自动化分析**: - 使用`trace_processor` Python API: ```python from perfetto.trace_processor import TraceProcessor tp = TraceProcessor(file_path="trace.perfetto-trace") print(tp.query("SELECT * FROM slice WHERE dur > 1e8")) # 查找>100ms事件 ``` 3. **与Systrace对比**: - Perfetto优势: - 支持GB级数据 - SQL分析引擎 - 统一Android/Linux追踪 > ⚠️ **注意**:深度分析相机HAL需厂商符号表,联系高通获取`camx.btf`调试文件[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值