9.2、不要猜:解析(Profile)
一般情况下,一个程序的执行时间有80%是耗费在20%的代码上的。在非常罕见的情况下,一个应用的每个代码块中所花费的时间是相同的,当出现这种情况时,优化量会变得很大。在这种情况下,必须要优化所有的代码块才能获得显著的性能改善。幸运的是,对于大部分应用来说,在找出了这关键的20%的代码后,仅仅对这20%的代码做重点优化就可以用最少的努力获得最大的回报。甚至只优化20%的代码可能也太多。Knuth建议集中在最能决定性能的那3%的代码。关键是要找出决定性的代码。
苹果的Xcode集成开发环境包含了一些用于找出性能瓶颈的工具。性能可能受限;于CPU或GPU或者强制一个处理程序等待另一个的同步事件。但是,在你使用强有力的分析工具之前,有一个快速简单的缩小性能问题的搜索范围的方法:注释掉应用的所有绘图代码并测试之后的“刷新率”。屏幕内容实际上不会变化,因为什么都没有绘制,如果这个应用甚至都不能按照所需的速度调用注释掉的代码,再怎么对绘图做优化都不能解决问题。在这种情况下,性能瓶颈不在绘图代码中。
当OpenGL ES渲染确实限制了应用性能时,可以使用苹果的OpenGL ES性能检测工具来找出所有GPU瓶颈。在很多情况下,这些工具能够直接为你指出检测到的应用代码,如果有的话,这就是限制OpenGLES性能的代码。这些工具甚至能够生成性能改进建议。
9.2.1 工具OpenGL ES Performance Detective
OpenGL ES Performance Detective 运行在你开发用Mac上。为了使用它,请确保要分析的应用已安装在iOS设备上,并且已与电脑连接。使用Xcode启动OpenGL ES Performance Detective,即在Open Developer Tool的子菜单中点击OpenGL ES Performance Detective菜单项。OpenGL ES Performance Detective会显示一个对话框让你选择连接哪一个设备以及分析哪一个应用。在iOs应用开始运行后,操作你的iOS应用直到到达你想测试的状态,然后点击OpenGL ES Performance Detective的Collect Evidence 按钮。 OpenGL ES Performance Detective会生成一个报告。
例如,当在例子OpenGLES_Ch9_1中开启平截体剔除后, OpenGL ES Performance Detective会生成下面的报告:
Summary
The frame rate of your app is not limited by the graphics pipeline .
Your performance is not limited by the OpenGL ES commands issued by
your app. Use the Instruments tool to investigate where your
application is bottlenecked.
例子OpenGLES_Ch9_1 每秒可以稳定生成30帧,即GLKViewController的preferred-FramesPerSecond属性的默认值。每次GPU在开始渲染下一帧之前会完成渲染当前帧。OpenGL ES Performance Detective没有报告的是完成每帧的渲染后还剩下多少时间。通过设置视图控制器的preferredFramesPerSecond属性为60来试着做更快的渲染,这个过程中可能会发现新的基于你的iOs设备的GPU速度的瓶颈。
当关闭基于视平截体的剔除后,OpenGL ES Performance Detective马上会检测到一个问题并提出解决方案:
Summary
The frame rate of your app is limited by the graphics pipeline.
Your performance is limited by the 0penGL ES commands issued by your app.
Top Suspect
GPU Vertex Processing
Reduce the number of vertices sent to OpenGL ES by simplifying your geometry. For
example:
1. Employ a polygon reduction algorithm.
2. 'Do not send unused vertex attributes. For example, do not send a normal when
lighting is disabled.
3. Use a Level of Detail (LOD) algorithm to avoid processing 1OOO's of triangles for
an object 10's of pixels on the screen.
4. Submit sorted indexed triangles. Sort both the index list and triangle list in
strip order.
5. Perform coarse object culling on the CPU.
6.
OpenGL ES Performance Detective的编号建议并不是按照它们应该被实施的顺序来列出的。对于例子OpenGLES_Ch9_1来说,按照编号5的建议重新开启基于视平截体的剔除就可以实现显著的性能提高。
9.2.2 工具Instruments
苹果的Instruments应用运行在MacOSX上,可以实现对于iOS应用执行时的几乎所有因素的详细分析。Instruments 应用自身会加载被称为“仪器”的各种不同工具来收集信息。你可以挑选可加载的“仪器”来改进分析。例如,Time Profiler可以有效地收集应用代码执行时的统计数据,并帮助找出最耗费时间的代码。如果Time Profiler 指示最耗费时间的是系统调用,那么可以使用SystemTrace来记录这个应用所做的所有系统调用。如果Time Profiler指示内存分配耗费的时间太多,那么可以使用Allocations来找出内存分配的源头。OpenGLESAnalyzer和OpenGLESDriver可以用来测量OpenGL ES活动。使用这些仪器逐个深入直到找到具体的瓶颈。
可以从Xcode4集成开发环境的Product菜单的Profile子菜单启动Instruments应用。启动后,最好的方式是使用这些可用“ 仪器”进行测试,感受一下它们所提供 的信息。也可以创建自定义的可加载“仪器”。苹果公司提供了Instruments的用户指南,地址为: http://developer.apple.com/library/ios/DOCUMENTATION/DeveloperTools/Conceptual/InstrumentsUserGuide/AboutTracing/AboutTracing.html。苹果公司经常更新、 改进,并扩展Instruments,这使得在线文档成为最好最新的用户指南。