分析嵌入式程序的处理延迟时,函数代码长短并不能直接说明耗时多少。有的函数内部计算较多,有的函数每次执行很快,却在一个业务周期里被反复调用。Green Hills MULTI可以记录程序运行情况,按函数和源码行查看时间分布。遇到偶发变慢,还可以结合执行历史,检查调用路径、中断和任务切换发生了什么。
一、Green Hills MULTI函数运行时间怎么查看
下面以英文界面的Profile窗口为例。不同目标连接和采集方式能够提供的数据不同,开始记录前,应确认当前环境支持采样、插桩还是硬件跟踪。
1、准备程序与调试信息
①、在【MULTI Debugger】中连接目标板,加载与板上程序对应的【可执行文件】和调试信息。
②、在【目标列表】中选择待分析的连接或任务,核对程序版本、测试输入及处理器时钟配置。
③、依次打开【View】→【Profile】,查看窗口中的采集说明。需要插桩性能数据时,按所用版本帮助配置构建选项,重新编译并加载程序。
调试信息负责将执行地址对应到函数和源码。程序重新构建后,旧记录可能对应另一份代码,因此每轮测试都应保留构建版本。
2、采集一段业务的性能记录
想看报文解析函数的耗时,可以围绕一批固定报文采集。把启动初始化和无关等待排除在记录范围之外,结果更容易解释。
①、在【Profile】中按当前目标的支持情况选择【Performance】,根据窗口提示点击【Start】。
②、运行程序并执行准备好的测试输入,到达业务结束位置后,在【Profile】中点击【Stop】。
③、打开生成的记录,切换到【Functions】,查找目标函数,查看可用的【Time%】和【Calls】等统计列。
④、选中函数,联动查看源码位置,记录本轮采集范围、输入数量和函数统计结果。
3、查看某一次调用的时间跨度
①、在目标支持跟踪采集时,录制包含目标函数完整调用过程的【Trace】数据。
②、打开【History】或【PathAnalyzer】,找到目标函数进入到返回的那一段,放大时间轴。
③、读取起止位置的时间坐标,计算跨度,同时检查期间的子函数调用、中断和任务切换。
这个跨度表示该次调用从开始到返回经历的时间,其中可能包含等待或抢占。采样占比适合查找累计热点,不能直接当作单次调用时长。
二、Green Hills MULTI性能分析如何定位耗时函数
查找热点时,可以先看哪些函数累计占比高,再追到具体语句和调用场景。仅看函数排名,还无法确定应该改算法、减少调用,还是调整资源访问。
1、从函数占比追到热点语句
①、在【Profile】的【Functions】中按【Time%】排序,选出占比较高的函数,记录函数名和所属任务。
②、检查【Calls】是否有有效数据。若采集方式提供调用计数,结合本轮业务量核对调用次数是否符合预期。
③、选中目标函数,查看【Source Lines】及调试器中的源码统计,定位占比较高的循环、计算和数据复制语句。
④、切换到汇编显示,核对热点【源码行】对应的实际指令,检查重复计算及分支执行情况。
例如,数据复制函数占比较高时,可以沿调用位置检查复制长度和调用次数。减少不必要的搬运,可能比修改复制函数内部代码更有意义。
2、追查调用路径与任务活动
有些函数只在少数几轮中变慢,这时整体平均占比可能掩盖问题。执行历史能帮助找到那一次异常调用。
①、在【History】或【PathAnalyzer】中定位较长的调用片段,查看该次执行经过的子函数和循环路径。
②、当前系统支持【EventAnalyzer】时,检查相同时间段内的中断、内核服务调用和上下文切换。
③、打开正常运行与较慢运行的【跟踪记录】,对照处理数据量、调用路径及抢占位置。
④、若时间跨度增加主要发生在等待阶段,回查对应【任务】的同步与资源访问。若目标函数持续执行计算,继续检查热点【源码行】。
三、Green Hills MULTI性能结果怎么核对?
性能记录受到采集范围、过滤设置和运行条件影响。优化前后的比较,应同时保留函数统计与业务完成时间,避免只看百分比变化。
1、确认时间占比的统计范围
①、查看【Profile记录】采用的数据类型,确认本轮统计来自采样、插桩还是【Trace】转换,并核对可以使用的统计项目。
②、打开【Filter】,检查【Percentage of】选择的是【Total Time】还是【Filter Time】。
③、比较两轮【Time%】前,将过滤条件和百分比分母设为一致,再核对两轮记录覆盖的任务及业务阶段。
④、分析多核程序时,核对记录是否汇总多个核心的活动,按当前工具支持范围限定【任务】或地址空间。
使用整个记录作分母,与只使用过滤范围作分母,同一函数会显示不同占比。函数代码没有变化,过滤条件改变也可能让排名发生变化。
2、保留基线并验证修改效果
一轮测试变快,还不足以判断修改是否稳定有效。输入规模、缓存状态和任务活动发生变化,都可能影响测量结果。
①、优化前,在【Profile】中选择【File】→【Save Displayed Recording】,将基线保存为【.gpro】,同时保留源码版本和构建配置。
②、固定输入数据、时钟和优化级别,修改后重新采集相同业务阶段,保存新的【性能记录】。
③、对照两轮【Functions】统计和业务完成时间,检查处理数量、输出结果及运行条件是否一致。
④、重复执行同一测试,观察耗时变化。需要整理记录时,通过【File】→【Export to CSV】导出统计数据,并标明各轮测试条件。
总结
MULTI的函数统计适合缩小排查范围,执行历史则有助于解释某次调用为什么耗时较长。处理热点时,把调用次数、代码路径和任务活动联系起来,修改方向会更明确。性能记录也应与源码版本和测试条件一起保留,方便后续验证与交接。希望这些操作能为嵌入式程序的耗时排查提供参考。
