详解Oculus性能调试工具OVR Metrics Tool各项指标
来源:映维网 作者 颜昳华
如果你曾尝试提升应用程序的性能,你或许已经知道OVR Metrics Tool或Logcat中的VrApi日志。OVR Metrics Tool是Oculus提供的性能工具,面向Unity,Unreal和原生开发者。平视模式允许你查看 VR 叠加层中的实时指标,而报告模式则在VR会话结束后提供性能报告。Oculus希望扩展在OVR指标工具中提供的信息,通过将其集成至操作系统中来进一步实现无缝的体验,以及构建允许你利用控制器来打开和关闭它的方法。
FPS是两者中最明显的统计信息,它对于判断应用程序是不是以全帧速率运行非常有用,但里面同时包含大量的其他信息。日前,Oculus的软件工程师Trevor Dasch撰文介绍了OOVR Metrics Tool,包含你可以忽略和不容忽视的信息。下面是映维网的具体整理,希望能够为你提供一定的借鉴参考:
OVR Metrics Tool参数和对应的VrApi日志值
1. 重要的参数
下面不是按字母顺序排列,而是按照重要性进行排列(或者至少是我认为重要的顺序排列)。当然,你可以始终通过Ctrl + F的方法来快速定位目标内容。
1.1 过期帧(每秒)
OVR Metrics Tool: STALE
VrApi Logs: Stale
你可能会惊讶于我没有将FPS放在第一位。但在评估用户体验的质量时,过时帧实际上是更有用的指标。什么是过时帧呢?由于VR的工作方式,屏幕显示刷新率并不直接与应用程序的帧渲染有关。取而代之的是一个名为合成器的中间步骤,即时间扭曲。它获取应用程序渲染的最后一帧,根据用户头部移动计算方向校正,并将其显示在物理显示器上。
所以,时间扭曲希望在特定时间渲染最后一帧。如果这一阵尚未准备妥当,则必须使用已经“过时”的前一帧。这与FPS有何不同呢?如果应用程序错过一帧,则过时帧加一,而帧速率减一,这似乎看起来形成了完美的抵消反比。但实际上并非如此。由于CPU和GPU并行工作,所以渲染一帧的时间可能会比单帧的总时长,但CPU或GPU花费的时间都不会比单帧更长。因此,一个应用程序可以72fps的速度运行,但每秒有72个过时帧。实际情况并没有那么糟糕,渲染和显示时间之间的延迟更长,但帧的释放速度却十分稳定。
然而,如果大于零但少于72的帧都过时,问题就会出现。这个时候,某些帧将连续显示两次,某些帧则会跳过。为了避免这种情况,我们使用一种“Extra Latency Mode/额外延迟模式”(如果使用的是Unity或Unreal,则默认是启用状态)。这告诉时间扭曲总是要等待额外一帧,而且除非第二帧之后都尚未预备好,否则不要认为它们已经过时。如果应用程序确实能够快速渲染,则将帧视为“早到”,但一切看起来都会十分流畅。
1.2 应用GPU时间
OVR Metrics Tool: APP T (in μs, 1/1000th ms)
VrApi Logs: App (in ms)
这可能是优化应用程序时要注意的最有用数据之一。应用GPU时间可提供渲染单帧所花费的时间。如果超过单帧长度(即72fps为13.88ms),则说明是GPU Bound。如果小于这个值,则可能是受CPU Bound。它在更改着色器,添加更多纹理,更改网格等同样非常有用,它可以显示GPU剩余的空间,以及是否添加了调试逻辑来打开和关闭特定对象,你可以判断所述对象的性能如何。在不捣鼓RenderDoc或Snapdragon Profiler等工具的情况下,这是最接近真实性能分析的方法。
1.3 CPU和GPU利用率
OVR Metrics Tool: CPU U和GPU U
VrApi Logs: GPU%和CPU%
对于确定应用程序是不是CPU Bound或GPU Bound非常有用,但你需要注意一定的问题。实际上,GPU利用率是更有用的指标,因为GPU在功能上属于单核(这不是GPU的工作方式,但就我们的比喻而言,不妨就采用这样的说法吧)。应用程序和时间扭曲都将工作提交给GPU,然后GPU执行工作,并且可以根据给定时间窗口执行的工作总量来计算单个利用率。如果达到100%,则说明是GPU Bound。如果仅仅由于调度而使它超过90%,你实际上可能已经开始遇到麻烦。实际上,CPU利用率不太有用。因为移动CPU属于多核,所以我们选择利用率来代表性能最差的核心(VrApi日志同时显示平均值和最差值)。但由于大多数应用程序都是多线程,而且调度程序会将线程分配给可用的核心,所以即便主线程运行非常缓慢,CPU利用率指标都可能无法表现出来,因为所述线程最终是由不同的核心运行。
要利用这个指标,你在调试时可以设置线程亲和性(thread affinity)并将主线程和渲染线程绑定到特定的核心。但这实际上会降低整个系统效率,因为调度程序非常擅长保持高吞吐量。所以,你可以保持关注,但不建议依靠它来确定负载的位置。你需要使用诸如systrace这样的分析器或引擎内置的分析器来寻找CPU端的瓶颈。
1.4 CPU和GPU运行级别
OVR Metrics Tool: CPU L和GPU L
VrApi Logs: CPU[X]/GPU (X是当前的主核心)
对于Gear VR,这些数字需要应用程序手动设置。但随着Oculus Go的推出,我们增加了自动动态时钟,如果应用未达到要求的帧速,它将增加这些数字。如果应用程序未实现所需的帧速率,你最好检查一下CPU和GPU的运行级别,因为它会在CPU Bound或GPU Bound时提供信号,以及各自的大致负载。例如,如果你注意到CPU运行级别为4,GPU运行级别为2,则需要优化CPU利用率。如果两者均为4,则需要看看我上面列出的其他指标。你同时应该记住,利用率数字需要结合相关的运行级别数字。例如,GPU Level 2和90%利用率的性能实际要优于GPU Level 4和60%利用率更高。
1.5 平均每秒帧数
OVR Metrics Tool: FPS
VrApi Logs: FPS
每秒帧数可能不需要太多解释。如果它与显示刷新率匹配,则没有太大问题。如果小于显示刷新率,则需要采取一定的措施。
1.6 可用内存
OVR Metrics Tool: A MEM
VrApi Logs: Free
报告的可用内存来自于Android OS。对于Android,内存以某种不透明的方式进行管理,所以这个数字难以实现。例如,如果应用程序进入后台,则新开的应用程序可能会占用大量内存,所以即便你有数百MB的可用空间,应用程序也可能会停止。但对于判断内存分配是否快于预期,或者是否有按预期地释放内存,这是一个相当不错的方法。
2. “知道最好”的参数
下面参数的重要性有所降低。它们主要用于判断应用程序的设置是否符合预期。当然,它们对于故障排除十分有用。
2.1 注视点渲染级别
OVR Metrics Tool: FOV
VrApi Logs: Fov
注视点渲染级别是指应用程序的固定注视点渲染强度。0为关闭,1为低,2为中,3为高,4为最高(仅支持Quest),其中屏幕的下半部分比上半部分更为清晰(对于显示双手的应用程序十分有用)。这个数字将直接影响GPU性能,并且在更改渲染级别时,屏幕边缘的可见伪影会越来越明显。为实现所需的性能提升,重要的是选择视觉可接受的渲染级别升。
2.2 眼图缓冲区宽度/高度
OVR Metrics Tool: EBW和EBH
这是纹理的渲染分辨率。Oculus Go/Gear VR的默认值为1024×1024,而Quest的默认值为1216×1344。这有助于确认你已将其改成期望值,并确认宽高比符合视角。分辨率直接影响GPU渲染时间,更多的像素意味着片段着色器需要更多的时间。
2.3 时间扭曲时间
OVR Metrics Tool: TW T
VrApi Logs: TW
这是时间扭曲渲染所花费的时间。这个时间与使用的层数及其复杂性直接相关(Equirect与Cylinder层的负载要高于Quad与Projection层)。大多数应用程序都无需担心这一点,但视频应用则不然,因为时间扭曲花费的时间过长会导致画面撕裂。
2.4 早到帧
OVR Metrics Tool: EARLY
VrApi Logs: Early
如前所述,在使用Extra Latency Mode/额外延迟模式时,可以在需要它们之前交付帧。可以忽略一些早到帧。如果你始终以较高的帧速率运行,请确保CPU/GPU运行级别不要高于实际情况。如果早到帧具有匹配的fps,我建议你关闭额外延迟模式。你同时可以通过增加分辨率或增加着色器复杂性来利用余量。
2.5 画面撕裂
OVR Metrics Tool: TEARS
VrApi Logs: Tear
这表明时间扭曲花费的时间太长并出现画面撕裂。这在早期的Gear VR设备更为常见。Oculus Go和Quest现在基本不会发生这种情况,除非应用程序使用了太多的层数(如使用Quad与Cylinder层来显示UI元素)。
2.6 已用内存
OVR Metrics Tool: U MEM
已用内存确实有用,但这个数字是用于说明PSS(Proportional Set Size)内存。因为应用程序可以在Android中共享内存,所以这会增加所述应用程序使用的所有唯一内存,并根据共享应用程序的数量来计算共享内存的一小部分。例如,如果两个应用程序使用一个占用20mb的库,则这将为每个应用程序的PSS增加10mb。这个指标可以跟踪应用程序分配了多少相对内存,但对于跟踪真实内存占用量没有什么用处。
2.7 额外延迟模式
OVR Metrics Tool: LAT
VrApi Logs: LAT
具体请参阅前面的过时帧部分。它几乎始终为1,这就是为什么尽管这个数字十分重要,但依然位于“知道最好”这个类别。
2.8 交换间隔
OVR Metrics Tool: SWAP
VrApi Logs: VSync
交换间隔告诉应用程序在渲染下一帧之前要跳过多少帧。它几乎始终为1,因为输入2可能会导致应用程序以一半的速率渲染,这可能会造成用户不适。Gear VR的省电模式会输入2,但我们从未在Oculus Quest启用。你可以将其用于调试目的,或者在极高分辨率时使用,但绝不应该在发行应用中启用所述功能,因为用户只要转头就会轻松注意到它。
2.9 预测时间
OVR Metrics Tool: PRED
VrApi Logs: Prd
预测时间是指应用程序在渲染前查询姿态和屏幕显示帧之间的绝对时间。根据引擎和显示器的刷新率,这几乎应该始终是40毫秒到50毫秒之间的固定数字。只有当数字比预期高得多的时候,这个参数才真正有用。它也不会告诉你有关延迟的全部故事,因为这是用于渲染的姿态,并且Unity和Unreal都是使用不同的姿态来更新 游戏 逻辑。
2.10 显示刷新率
OVR Metrics Tool: DRR
对于Oculus Go和Oculus Quest,显示刷新率可以是60或72。这个指标仅告诉你当前的设置。如果屏幕刷新为72,但你看到FPS为60,这会十分有用。这意味着你需要进行大量的优化。
2.11 电池电量
OVR Metrics Tool: BAT L
对性能分析没有帮助,但如果你想在应用程序中电池电量监控,这没有什么问题。
3. “对Gear VR略略有用,但忽略也没有问题”的参数
下面的指标仅对Gear VR有用。对于Oculus Go和Quest,由于硬件固定,温度也不是问题,所以你可以进行忽略。下面同时列出了可能对我们团队以外的任何人都没有用的参数。
3.1 传感器温度
OVR Metrics Tool: TEMP
对于早期的Gear VR,温度可能是个问题。当低功率 手机 的时钟以VR所需的速度运行时,它们可能会迅速变热,从而可能导致可怕的“过热”屏幕。随着智能手机的性能提升,这已不再是一个问题,但如果你依然将S6和S7作为目标,则可以进行监控。
3.2 电源管理
OVR Metrics Tool: POW L
这个指标告诉你设备是否处于省电模式,报告的三个级别是NORMAL = 0,SAVE = 1,DANGER =2。随着设备升温,功率级别将自动从NORMAL更改为SAVE,并最终变为DANGER。一旦达到DANGER,系统将显示过热对话框。对于应用程序,你可以查询当前功率级别,所以建议你将应用程序设置成达到SAVE状态,从而降低渲染成本。有关这一话题的更多信息,请参阅我们的电源管理文档。
3.3 CPU/GPU/内存频率
OVR Metrics Tool: CPU F, GPU F和MEM F
这是CPU/GPU/内存的时钟速度,当CPU运行级别或GPU运行级别更改时,时钟速度将更改。这对于监控并不是很有用,因为原始数字并不能提供采用不同SoC的设备之间的性能差异。
3.4 电池温度
OVR Metrics Tool: B TEM
电池的当前温度,对Gear VR更为重要。
3.5 电池/电源电流,电源电压
OVR Metrics Tool: BAT C, POW C和POW V
电池电流以毫安为单位,电压以伏特为单位。从理论上讲,你可以对其进行监控并确定消耗的电量(Apms×Volts=Watts),但最好的做法是针对CPU/GPU运行级别和利用率进行优化。
3.6 遥控器/控制器温度
OVR Metrics Tool: LC TM and RC TM (formerly R TEM)
控制器的温度
3.7 最大转速
OVR Metrics Tool: M ROT
头显的最大转速
4. VrApi日志参数
VrApi日志包含大量与OVR相同的统计信息,但它统计了少数独特的信息,而具体的用处将取决于你的特定需求。
FPS={FPS},
Prd={Prediction}ms,
Tear={Tears},
Early={Early},
Stale={Stale},
VSnc={Swap Interval},
Lat={Extra Latency Mode},
Fov={Foveation Level},
CPU{Measured CPU Core}/GPU={CPU Level}/{GPU Level},
{CPU Frequency}/{GPU Frequency}MHz,
OC={Online Core Mask},
TA={TimeWarp Thread Affinity}/{Main Thread Affinity}/{Render Thread Affinity},SP={Timewarp Scheduling Priority}/{Main Thread Scheduling Priority}/{Render Thread Scheduling Priority},
Mem={Memory Frequency}MHz,Free={Available Memory}MB,
PSM={Power Save Mode},PLS={Power Level},
Temp={Battery Temperature}C/{Sensor Temperature}C,
TW={TimeWarp GPU Time}ms,App={App GPU Time}ms,
GD={Guardian GPU Time}ms,
CPU&GPU={CPU & GPU Time}ms,
LCnt={Layer Count},
GPU%={GPU Utilization},
CPU%={Average CPU Utilization}(W{Worst Core CPU Utilization})
这些指标按照它们在VrApi日志行中出现的顺序进行排序。我已经对每个参数进行了注明,并给出了我个人的实用性评分(满分5分)(根据需要,你可能会发现它们或多或少地有用)。
4.1 Measured CPU Core
实用性评分 1/5
这个数字仅表示报告CPU频率时正在测量的核心。对于大多数CPU架构而言,其具有大小不一的内核,除非将CPU Level设置为0,否则它将成为大核心。
4.2 Online Core Mask
实用性评分 0/5
当CPU运行级别设置较低时,较旧的Gear VR会断电。现代CPU不再这样做,并且可以在不使核心脱机的情况下减少核心的能耗。所以,它并不是十分有用。
4.3 TimeWarp/Main/Render Thread Affinity
实用性评分:3/5
这表示各种线程的线程亲和性。这对于判断线程是否在大核心上运行十分有用,但如今最好避免手动设置亲和性。对于Quest,TimeWarp将显示为0。
4.4 TimeWarp/Main/Render Thread Scheduling Priority
实用性评分:4/5
这表示线程的优先级。“F” = SCHED_FIFO是最高优先级,“N” = SCHED_NORMAL。时间扭曲应该始终是“F”,但对于Quest它是“N”。如果你将Main和Render传递给vrapi_SetPerfThreads(UE4会自动执行这个操作),它们将会设置为F。
4.5 Power Save Mode
实用性评分:0/5
省电模式是一个二进制值,仅表示电源管理是不是SAVE。
4.6 Guardian GPU Time
实用性评分:3/5
与应用GPU时间和时间扭曲GPU时间类似,我们测量并报告防护系统GPU时间。当然,这只会对Quest有用。关于这个数字,你不能做什么。所以除了告知你防护系统的GPU时间之外,它并不是非常有用。
4.7 CPU & GPU Time
实用性评分:5/5
这是应用程序渲染一帧所花费的总时间。当前仅在使用Unity或Unreal引擎时可用,并且是测量从Render或RHI线程开始处理帧直到GPU完成渲染为止。从中减去应用GPU时间可以计算出Render线程的大约时钟时间。如果这是你的瓶颈,所述参数可能会很有用。
4.8 Layer Count
实用性评分:3/5
时间扭曲每帧渲染的层数。这包括诸如防护系统之类的系统层。你最好关注一下,因为这个数字与时间扭曲GPU时间之间存在直接的相关性。将它保持在最小值将有助于避免画面撕裂。
5. 深入挖掘
尽管OVR Metrics Tool和VrApi日志可允许你轻松访问一些关键的指标,但这通常只是通往RenderDoc和SnapDragon Profiler等工具的第一步。主要的游戏引擎同样包括用于调试CPU瓶颈的优秀性能分析工具。
原文链接:https://yivian.com/news/68288.html