Android Systrace的部分Tag含义

news/2024/12/17 11:02:49/文章来源:https://www.cnblogs.com/linhaostudy/p/18611893

systrace的一些tag标签的含义和作用。

1. CPU*(0-7)

Kernel内核模块,可以查看各个CPU执行了什么进程任务。

cpu信息的目录是/sys/devices/system/cpu,例如我的一加六老设备:

OnePlus6:/sys/devices/system/cpu $ ls
core_ctl_isolated cpu4    cpuidle               isolated   possible 
cpu0              cpu5    gladiator_hang_detect kernel_max power    
cpu1              cpu6    hang_detect_gold      modalias   present  
cpu2              cpu7    hang_detect_silver    offline    uevent   
cpu3              cpufreq hotplug               online    

2. HW_VSYNC_ON_XXX

  • 值:1表示HW VSYNC信号被打开,0关闭
  • 出现时间:HW VSYNC硬件信号被打开/关闭的时候
  • 含义:
  1. HW_VSYNC_ON_XXX后面的XXX表示display id(可通过dump SurfaceFlinger查看),用于区分不同屏幕的HW VSYNC硬件信号
  2. HW VSYNC硬件信号之所以会有时候被打开/关闭,是因为目前Android Graphics/Display依赖的信号不是硬件信号,而是软件信号 —— DispSync。硬件信号的主要作用是用于校准,打开的时机是当软件VSYNC的误差超过一定值后,DispSync会打开HW VSYNC硬件信号进行校准
  • 作用:用作分析硬件模块导致的BUG的时间点

2.1. fence同步机制简单释义

BufferQueue中的Buffer在整个绘制、合成、显示的过程中,一直在 CPU,GPU 和 HWC 之前传递,某一方要使用 Buffer 之前,需要检查之前的使用者是否已经移交了 Buffer 的“使用权”。而这里的“使用权”,就是fence。当fence释放(即signal)的时候,说明 Buffer 的上一个使用者已经交出了使用权,对于 Buffer 进行操作是安全的。

在 Android 里面,总共有三类fence:acquire fence,release fence 和 present fence。其中acquire fence和release fence隶属于Layer,present fence隶属于帧(即 Layers):

  • acquire fence:App将Buffer通过queueBuffer()还给BufferQueue的时候,此时该Buffer的GPU侧其实是还没有完成的,此时会带上一个fence,这个fence就是acquire fence。当SurfaceFlinger/HWC要读取Buffer以进行合成操作的时候,需要等acquire fence释放之后才行
  • release fence:当App通过dequeueBuffer()从BufferQueue申请Buffer,要对Buffer进行绘制的时候,需要保证HWC已经不再需要这个Buffer了,即需要等release fence signal才能对 Buffer进行写操作。
  • present fence:在HWC1的时候称为retire fence,在HWC2中改名为present fence。当前帧成功显示到屏幕的时候,present fence就会signal

3. HW_VSYNC_XXX

  • 值:值发生变化(0->1 / 1->0)是表示当前时刻发出了HW VSYNC硬件信号
  • 出现时间:上面HW_VSYNC_ON_XXX打开的时候
  • 含义:
  1. HW_VSYNC_XXX记录的是当前时刻收到了HW VYSNC硬件信号
//frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
//Step 1: 当收到硬件信号后,回调该函数
bool HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp) {const auto displayId = toPhysicalDisplayId(hwcDisplayId);......const auto tag = "HW_VSYNC_" + to_string(*displayId);ATRACE_INT(tag.c_str(), displayData.vsyncTraceToggle);//Step 2: 取反赋值给HW_VSYNC_XXX,即systrace中该值0和1之间的变化displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle;return true;
}

4. hasClientComposition

  • 值:布尔值,1表示本次SurfaceFlinger合成存在GPU合成的layer,0表示本次合成的所有layer都不是GPU合成
  • 出现时间:SurfaceFlinger的doComposition合成开始
  • 含义:
  1. Client合成(GPU合成)是通过CompositionEngine调用一系列的OpenGLES接口完成合成
  2. Device合成(硬件合成)是使用Hardware Composer进行合成。

优势:省电

劣势:某些场景无法进行Device合成,比如Layer是圆角的,Layer的总数超过硬件上限

  • 作用:如果发现本应该是Device合成的场景出现hasClientComposition值为1的情况,则可结合dump SurfaceFlinger信息分析合成策略是否有问题

5. FrameMissed/GpuFrameMissed/HwcFrameMissed

  • 值:1表示上一次合成有FrameMissed/GpuFrameMissed/HwcFrameMissed,0则没有
  • 出现时间:SurfaceFlinger的INVALIDATE阶段开始
  • 含义:FrameMissed/GpuFrameMissed/HwcFrameMissed表示的是上一次合成的结果,当SurfaceFlinger合成后显示到屏幕上显示一帧,present fence就会signal。因此可以将present fence signal作为一次合成完结的标志。SurfaceFlinger每次开始被Vysnc-sf唤醒时,会先检查上一次合成情况,方式就是检查上一次合成的present fence有没有signal。如果没有,则认为是FrameMissed,并结合上一次合成方式是否有GPU或者HWC参与,同步GpuFrameMissed/HwcFrameMissed信息。
  • present fence没有及时signal主要有两种原因:
  1. Display问题
  2. APP/游戏的GPU负载过高:上层GPU负载过高会导致底层大部分时间都在等GPU渲染工作完成,延迟了present fence的signal,导致FrameMissed
  • FrameMissed作用:
  1. 统计丢帧
  2. Android有一个debug开关,可以在检测到上一帧有FrameMissed出现的时候,跳过本次的合成,留给底层更多的时间去显示。这个初衷是好的,不让底层过于繁忙,通过主动跳过合成来减缓底层的工作量。但是由于跳过合成就相当于主动丢帧,在某些场景下会导致到持续性的掉帧。因此这个开关一般是不会打开的。

6. VSYNC-sf/VSYNC-app

  • 值:表示SurfaceFlinger和APP发出Vsync信号(刷新率60是16.67ms,刷新率90是11.11ms)
  • 出现时间:DispSync分发的时候
  • 作用:分别针对SurfaceFlinger合成和APP应用渲染的起点。如果一处没有Vsync-sf,则说明此处有丢帧情况,原因可能是上面的FrameMissed,或者是APP没有及时完成渲染导致丢帧

6.1. VSYNC-app基本不变化的原因

现在绝大部分手游都使用游戏引擎,例如Unity、Unreal,这些引擎会自己去控制刷新率。

例如和平精英、王者荣耀可以有多个帧率档位选择,所以就不会通过Vsync-app的速率进行绘制刷新。


7. queueBuffer

Systrace中抓取的都是CPU侧的,例如每个CPU核的频率、C-State、运行了什么线程、线程间的调用关系、运行时长等。

而生产者通过dequeuebuffer获取buffer后,会最终交给GPU渲染绘制,然后通过queuebuffer将buffer还给BufferQueue。

如果GPU渲染的时间长,则可以初步判断性能问题是出自于GPU侧

7.1. FenceMonitor

Android Q在libgui库引入新的内部类FenceMonitor,作用是跟踪Fence的生命周期,在Systrace中展示一个Fence从产生到signal需要的时间。

  1. 在Systrace中GPU Completion的每个waiting for GPU completion ×××的长度,大致可以作为GPU渲染所花费的时间(即acquire fence释放的总时间),但是并不严谨(解释如下)。

通过这个时间,可以判断是否有GPU bound的现象。

  1. 相对应的,waiting for HWC release ×××的长度大致可以作为release fence的释放总时间参考。在release fence signal之前,GPU是无法对dequeuebuffer拿到的Buffer进行读写的(因为此时Buffer还是归HWC所有)。

通过这点,可以判断Display是否有问题。

:systrace上的fence信息只能准确反映出signal的时间点,但无法反应出gpu/display开始干活的时间点。

再说原因:systrace上等待GPU fence的起始时间是从queueBuffer开始算的,而不是gpu真正开始干活时才算的。queueBuffer执行完成并不意味着gpu就能马上开始干活,有可能这个时候是因为display还没有释放(即signal)该buffer导致gpu不得不等在那里。所以我们不能说等待gpu的fence耗时就是gpu渲染的时间。同样的,HWC release fence也是一样的道理。

但有时候我们可以变相的计算出gpu的耗时:GPU complete signal的时间点,减去上一帧HWC release fence signal的时间点,这样计算出来的结果也只能是个近似值,因为从display buffer释放到gpu真正开始干活,这中间还有额外的准备时间。当然,有的时候systrace上反应不出HWC release fence signal的时间点,因为在dequeueBuffer的时候该release fence就已经释放了,所以上面的公式就排不上用场了。


FenceMonitor相关代码:

//frameworks/native/libs/gui/Surface.cpp
//内部类
class FenceMonitor {
public:explicit FenceMonitor(const char* name) : mName(name), mFencesQueued(0), mFencesSignaled(0) {std::thread thread(&FenceMonitor::loop, this);pthread_setname_np(thread.native_handle(), mName);thread.detach();}......
}int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {ATRACE_CALL();ALOGV("Surface::dequeueBuffer");.....if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {//申请到Bufferstatic FenceMonitor hwcReleaseThread("HWC release");hwcReleaseThread.queueFence(fence);}.....
}int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {ATRACE_CALL();ALOGV("Surface::queueBuffer");.....if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {//GPU绘制完成static FenceMonitor gpuCompletionThread("GPU completion");gpuCompletionThread.queueFence(fence);}return err;
}

8. 参考

  • Android Systrace如何抓取分析问题
  • Systrace 中的这些 tag 究竟是什么意思(一)
  • 如何通过 Systrace 查看 GPU 渲染花费的时间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/854233.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

提升教育团队效率与个人学习!哪些办公软件堪称神器?

在教育领域,无论是教育教培团队的日常运营,还是个人备考者的学习提升,高效的协作与管理工具都至关重要。对于注重计划和秩序的 J 人来说,可视化团队协作办公软件更是能契合其工作和学习风格,助力他们更好地达成目标。本文将为您盘点 6 款此类软件,包括国内的板栗看板以及…

看板助力年末总结规划:任务分解与进度跟踪全攻略

一、年末规划的重要性 每年的年末,企业都需要做一次深度的反思和总结,分析过去一年的业务发展、财务状况、市场表现以及团队协作等方面的成绩与不足。年末规划不仅是对过去一年的回顾,更是为来年制定清晰目标和行动计划的基础。具体来说,年末规划的核心要素包括: 总结过去…

课程Project总结 - 移动web大作业(不看微博)

移动web最后的大作业我们组做的是实现类似新浪微博的功能。基本功能包括修改个人信息、发微博、看微博和回复数据库设计微博。我认为整个工程可以分为数据库设计、前台HTML、JSP和CSS开发、后台JavaScript设计。下面就依次看这几个部分 数据库设计用户类:登录不看微博的用户,…

C# static关键字—— 对象引用对于非静态字段、方法或属性是必需的

原文链接:https://blog.csdn.net/Jeffxu_lib/article/details/96425138 在 C# 中,当主函数调用另一个非静态函数时总是提示: “ 对象引用对于非静态的字段、方法或属性是必需的 ” 一、错误分析 1、因为 f02() 是非静态函数;而主函数 Main 前有关键字 static ,其为静态函数…

管道传输

提交运行 ls | sort -r的结果,总结管道的功能 管道的功能总结: 数据流传输: 管道允许将一个命令的输出直接传输到另一个命令的输入,无需中间文件。 命令组合: 可以组合多个命令,实现复杂的数据处理流程。 效率提升: 由于数据在内存中直接传输,避免了磁盘 I/O,提高了处…

网站颜色在哪里修改图片,网站颜色和图片修改指南

修改网站的颜色和图片可以提升网站的视觉效果和用户体验。以下是详细的步骤:备份文件:使用FTP工具(如FileZilla)下载网站的所有文件。 确保备份文件的安全。编辑CSS文件:使用代码编辑器(如VS Code、Sublime Text)打开style.css文件。 根据需求修改颜色。例如,修改背景颜…

寻找教育团队协作神器!J 人备考有何优质软件可选?

在教育领域,无论是教育教培团队的日常运营,还是个人备考者的学习提升,高效的协作与管理工具都至关重要。对于注重计划和秩序的 J 人来说,可视化团队协作办公软件更是能契合其工作和学习风格,助力他们更好地达成目标。本文将为您盘点 6 款此类软件,包括国内的板栗看板以及…

Z-BlogPHP 中“主题模板的编译文件不存在”错误的原因是什么?

“主题模板的编译文件不存在”错误通常出现在 Z-BlogPHP 中,表示系统未能正确编译主题模板文件,导致无法正常显示网站内容。以下是常见的原因和解决方法:缓存文件未生成:缓存文件未生成或已损坏,导致系统无法找到编译后的模板文件。 解决方法:登录 Z-BlogPHP 后台管理界面…

如何在 Z-BlogPHP 中临时禁用所有插件以排除插件冲突?

在 Z-BlogPHP 中,如果遇到网站无法正常运行的问题,可能是由于某个插件引起的冲突。为了排除插件冲突,您可以临时禁用所有插件,然后逐步启用插件以确定问题所在。以下是具体的操作步骤:确定问题原因:首先,确认问题是否与插件有关。常见的插件冲突症状包括网站无法加载、后…

如何使用 Lambda 自动添加CloudWatch所有实例磁盘告警及 SNS 通知

利用Lambda轻松实现EC2实例监控 最近新增了一些服务器,因为每个服务器的基础监控都是要做的。我就想,如何能够快速便捷的方式把这些基础指标都监控上呢?本文将详细介绍如何通过Lambda自动为所有EC2实例添加CloudWatch磁盘告警,并在磁盘利用率超过阈值时,通过SNS主题发送通知…

实现hive的bitmap同步到doris

背景: 官方提供的方案不可行 doris提供的hive-udf中:https://doris.apache.org/zh-CN/docs/3.0/ecosystem/hive-bitmap-udf 官网方式如下: 需要使用doris外接hive的元数据地址:hive.metastore.uris 这里有个问题是,很多公司都会有数据安全和权限控制,这个接口一般不会外露…