I am writing a video processing app and have come across the following performance issue: Most of the methods in my app have great differences between cpu time and real time.
I have investigated using the DDMS TraceView and have discovered that the main culprit for these discrepancies is context switching in some base methods, such as MediaCodec.start() or MediaCodec.dequeueOutputBuffer()
MediaCodec.start() for example has 0.7ms Cpu time and 24.2ms Real time. 97% of this real time is used up by the context switch.
This would not be a real problem, but the method is called quite often, and it is not the only one that presents this kind of symptom.
I also need to mention that all of the processing happens in a single AsyncTask, therefore on a single non-UI thread.
Is context switching a result of poor implementation, or an inescapable reality of threading?
I would very much appreciate any advice in this matter.
答案 0 :(得分:3)
首先,我怀疑时间实际上是花在上下文切换上。 MediaCodec.start()将花费一些时间等待mediaserver进程与视频驱动程序通信,这可能是您所看到的。 (除非您使用的是软件编解码器,否则您的流程不会执行任何实际工作 - 它会将IPC请求发送到与硬件编解码器通信的mediaserver。)它可能的跟踪视图是只是报告时间去向的最佳猜测。
其次,AsyncTask线程在lower priority执行。由于MediaCodec应该在硬件编解码器中完成所有繁重工作,这不会影响吞吐量,但它可能会对延迟产生影响,因为其他线程将优先考虑其他线程。调度。如果您担心性能,请停止使用AsyncTask。您可以自己进行线程管理,也可以使用java.util.concurrent中的方便帮助程序。
第三,如果你真的想知道在涉及多个线程和进程时发生了什么,你应该使用systrace,而不是traceview。可以找到使用systrace和自定义跟踪标记(以观察CPU核心旋转)的示例here。