我在Android 4.2.2上的非根Nexus 4上使用systrace测量我的应用程序的性能.我在报告中看到一些对我没有意义的事情,我想知道它们是否可能是systrace错误,或者是否有人可能知道这些症状可能的根本原因.
链接到报告 - 请查看运行结束时的大曲线(~18s).我的理解是performTraversals处于框架级别,它绘制了用户界面的单个框架.所以对我来说没有任何意义,它下面可能会有递归调用.另外,因为我在运行结束时得到了这种指数堆栈,我认为这实际上只是运行结束时数据的systrace缺陷.这种递归是否可能?这是什么意思?
链接到报告 - 有趣的行为开始于12秒左右.当我在跑步中间看到类似的东西时,我想我也许不应该写下这个.此外,我花了很多时间试图弄清楚什么可能会占用这么长的eglSwapBuffers/queueBuffer(我的应用程序不使用openGL,只是直接使用框架)无济于事,当一位同事告诉我只是忽略它因为交换缓冲区总是瞬间完成的.可能还有更多吗?这里有什么需要调查的吗?
我正在调查我的应用程序的性能,因为我注意到它在滚动时丢弃了一些帧.我运行systrace(在运行4.3的Nexus 4上),并在输出中注意到一个有趣的部分.
一开始一切都很好.放大左侧部分,我们可以看到绘图从每个vsync开始,完成备用时间,并等到下一个vsync.由于它是三重缓冲的,因此应该将其绘制到一个缓冲区中,该缓冲区将在完成后发布在以下vsync上.
在放大屏幕截图中的第4个vsync上,应用程序执行了一些工作,并且绘制操作没有及时完成下一个vsync.但是,我们不会删除任何帧,因为之前的抽奖正在提前一帧.
在这种情况发生之后,绘制操作不能弥补错过的vsync.相反,每个vsync只启动一个绘制操作,现在它们不再向前绘制一个帧.
放大右侧部分,该应用程序会做更多工作并错过另一个vsync.由于我们没有向前绘制一个帧,所以实际上帧丢失了.在此之后,它会回到前方画一帧.
这是预期的行为吗?我的理解是,如果你错过了一个vsync,三重缓冲允许你恢复,但是这种行为看起来像每两个你错过的vsyncs一次丢帧.
跟进问题
在此屏幕截图的右侧,应用程序实际上渲染缓冲区的速度比显示器消耗它们的速度快.在performTraversals#1(屏幕截图中标记)期间,假设正在显示缓冲区A并且正在渲染缓冲区B. #1在vsync之前完成,并将缓冲区B放入队列中.此时,应用程序是否应该能够立即开始渲染缓冲区C?相反,performTraversals#2直到下一个vsync才开始,浪费了宝贵的时间.
同样地,我对左侧对waitForever的需求感到有些困惑.假设正在显示缓冲区A,缓冲区B在队列中,并且正在渲染缓冲区C. 当缓冲区C完成渲染时,为什么不立即将它添加到队列中?相反,它会执行waitForever,直到从队列中删除缓冲区B,此时它会添加缓冲区C,这就是为什么无论应用程序渲染缓冲区有多快,队列似乎始终保持大小为1.