http://blog.manbolo.com/2012/11/20/using-xcode-opengl-es-frame-capture这里是原文,因为它版本比较老和它demo的限制,所以也想写一个基于Xcode6上基于3d渲染的分析的教程
Xcode和Visual Studio的一个主要差别,还是再Xcode有一套免费的的性能工具,例如Instruments,不过对于图形程序员来说,Xcode最强大的功能还是可以捕获和分析OpenGL ES和最新Metal framewrok的Frame。这个工具叫GPU Frame Capture(Xcode6.x),可以查看OpenGL和Metal的缓冲,以及GLES Shader和Metal shader。这里也是一个如何再你的App上运用它的快速教程。
教程里的例子和代码来源于UE4的Sun Temple 工程和Apple开发者网站上的MetalDeferredLighting工程
https://developer.apple.com/library/ios/samplecode/MetalDeferredLighting/Introduction/Intro.html
1 设置 GPU Frame Capture
这里是Apple开发文档上关于GPU Frame Capture的简介,
https://developer.apple.com/library/ios/documentation/ToolsLanguages/Conceptual/Xcode_Overview/chapters/about.html如果要使用这个功能,至少要是Xcode4.5以上(Metal的话必须是Xcode6.x),而且必须是在真机上,并连接运行Xcode的Mac,如果渲染api是metal frame的话,必须是ios8的系统,iphone5s,ipad air,级别的设备上。
另外需要把GLKit或OpenGL Framework加入到代码里,然后在菜单选择Product > Manage Schemes,双击你的app的Scheme,然后进入编辑
点击Run这个scheme,然后在Options的标签上设置GPU Frame Capture,默认打开是Automatically Enabled,不过因为GLES和Metal同时存在的缘故,建议强制设置为OpenGL ES或Metal(例如基于UE4的app)。
2 捕获 Frame
然后你就可以捕获你要调试的app的Frame了,在Debug模式下运行App (Product > Run or ⌘R),当你的app在真机上完全加载后,就可以进入 Debug Navigator (View > Navigators > Show Debug Navigator,或直接点击左侧代码栏上的小图标),再点击Debug Navigator上的FPS标签
例如下图,你可以看到你的App的更新的FPS显示,以及左侧不同的测试项目,而程序员的目标就是让它达到60FPS,而我们的Sun Temple这个时候只有26FPS左右,需要我们找到性能的瓶颈
在编辑器里,我们可以看到CPU和GPU的消耗时间毫秒数,如果想要达到60 FPS,那么CPU和GPU时间应该只有16毫秒,30FPS的话是32毫秒,而这里例子里,CPU消耗38有些超过限制了。
从这里可以看出,我们的主要瓶颈不在GPU上,而是在我们的代码调用上,为了获得更好的信息,我们可以捕获一个gputrace,来查看每帧渲染内部的具体流程,我们在Debug的输出窗口上,点击照相机图标获取整个Frame。
点击Capture Frame图标后(根据程序的大小捕获需要等几~十几秒),你就可以在Debug Navigator里访问OpenGL或Metal的Frame了
而在移动设备上,你可以看到程序显示的事当前捕获的那帧,并暂停了,在Debug Navigator上,如果你把不同的图标
展开,也可以看到捕获Frame内部的OpenGL/Metal调用,Debug Navigator会把与这帧(包括你的代码调用栈)关联的每一个Draw Call和State Call都显示在编辑器面板上,而State的信息,也会显示在下方的Debug面板上。
如果你没有看到Object面板的话(蓝框部分),可以点击show assistant Editor,然后选择想显示的类型,如果Mac设备不是太好,而游戏又是类似UE4这种大型图形程序,选择All需要慎重。
你可以通过在整个buffer面板上右键选择Show/Hide Draw Call Highlight,把当前draw call绘制的三角面用亮绿色高亮出来。
3 查看OpenGL/Metal的对象
在assistant编辑窗口,你可以访问OpenGL对象,例如Buffer,VAO,以及绑定或未绑定的Texture,还有shader programes:
可以查看Array Buffer里的内容
点击Shader,会显示对应的shader源代码
这样就可以很简单的获得所有的shader代码了
4 性能的改善
为了方便考虑,这里使用的之前u3d上一个IBL的优化案例,Cpature GPU Frame后,从图中可以看到,这个app的瓶颈主要在GPU上的某个shader
那么我们需要对这个shader做优化,在这个program上双击,可以在辅助编辑器窗口看到shader代码(可惜的是,UE4和Unity3d的shader都是用glsl-optimizer优化过的,可读性并不是那么高了)
这里的textureLod是有些消耗的,第3项lod值是用来索引CubeMap的mip,来实现IBL材质的粗糙效果,这个我们把它改为1.0
点击左下角的刷新图标。然后就可以看到修改后的效果,下图中,蓝色的修改前的情况,绿色是当前的情况,修改为1.0后效率提高的原因,是如果一开始lod是定值的话,texture就再shader运行前pre fetch,就需要再每个像素的pixelshader里重复加载这个cubemap里,从而起到了优化的作用
然后,你可以回到Unity或UE4里,对shader源代码再做一次修改,就起到了优化的作用了
5 保存和分享捕获的Frame
最后,你可以导出和保存你捕获的GPU Frame,不需要源代码,就可以把它分享给其他人,例如一个可以电话帮你解决的OpenGL或Metal的专家
只是这种保存方式比较尴尬,目前还没有更好的方式来保存,特别是在Xcode6.x版里。首先在菜单里选择Navigator>Open in..
点击左侧的+的符号,然后给UE4Game.gputrace创建一个新的窗口
在新创建的窗口的(*.gputrace)的文字上右键
你可以看到上图第2个com.apple.dt.xxxxx里保存的就是.gputrace临时保存的位置了,你可以把它保存到你的其他目录下,如果你想重新打开或分享给其他人,只需要连接移动设备到你的Mac,并双击这个*.gputrace,然后可以在编辑器里看到下图的对话框:
点击Replay Trace,然后就会进入这个文件的保存的Frame模式里,非常方便
网友评论