如何分析音频回调
Posted
技术标签:
【中文标题】如何分析音频回调【英文标题】:How to profile audio callback 【发布时间】:2014-01-27 09:04:55 【问题描述】:我正在写一个音乐播放器。我已经做了很多工作来提高我的音频回调的性能:
所有解码等当然是在单独的线程中完成的。这会填满一些缓冲区。
为了避免任何锁定,我避免了任何互斥体,并仅基于原子操作对所有相关结构进行编码。它基本上是一个无锁 FIFO。
我尝试通过在所有分配的内存上使用mlock
来避免页面错误。
我通过thread_policy_set
(类似于here)将我的线程设置为实时约束。
有时仍然会发生下溢。我想知道如何调试它,因为我想知道是什么导致了它们。
我正在考虑一种方法来跟踪音频回调的当前执行,如果它花费的时间超过 2 毫秒左右。但是我该怎么做呢?
另外,它可能仍会读取一些内存,从而导致页面错误。我该如何调试这些?
回调中的所有代码仍然有些复杂。也许只是太复杂了。我可以通过引入另一个间接来解决这个问题,并通过仅使用一个简单的环形缓冲区使代码真正最小化。这会带来更多的延迟,我不确定这是否真的是问题所在。
【问题讨论】:
你看过 Instruments 吗? Time Profiler & System Trace(显示线程调度)应该会给你一些洞察力。 您的目标缓冲区大小/采样率是多少?即您在回调中总共有多少时间?只是问一下,因为我们有软件可以在 @RhythmicFistman:我这样做了,但并没有太大帮助,因为它们只显示平均数字而且看起来不错。下溢很少发生。我需要以某种方式找到一种方法来仅在需要太长时间时才捕获跟踪。 @stijn:即使在 48kHz 时也会发生这种情况,但理想情况下我希望它也支持 96kHz 或 192kHz。我尝试了几种缓冲区大小,但没有太大帮助。但也许这也是我的中间层 PortAudio 的问题。当我让操作系统自动选择缓冲区大小时,我得到了最好的结果。 作为第一步,然后尝试确定是否是您的代码而不是导致问题的任何底层层?找出代码在回调中花费的最小/最大时间量。如果它从未接近最大可能数量,那么您的代码不是罪魁祸首。 【参考方案1】:我会尝试的是,如果我有一个应该在 2ms 内完成的程序,我会在进入程序时设置一个 2ms 的闹钟中断,并在退出程序时清除它。 即使加班很少发生,这也一定能搞定。
所以当中断发生时,我可以在调试器中捕获它并检查堆栈。 这会在做需要额外时间的事情时抓住它吗? 也许,也许不是,但多做几次,一定会发现一些有趣的事情。
我要做的另一件事就是在回调本身中寻找加速。 为此,我会在它运行时随机手动暂停它多次,并且每次都检查堆栈。 我会简单地忽略回调不在堆栈上的任何样本。 对于剩余的样本,回调在堆栈上,它将位于回调状态序列中的随机位置,因此很有可能如果它正在做任何优化可以节省大量时间的事情,我会看到它在做它。
【讨论】:
我认为即使是回调中的系统调用也被认为是坏的,因为它们可能会阻塞,但对于调试来说,这可能还可以。 :) @Albert:如果回调中有阻塞的系统调用,那么暂停会找到它们,如果它们占用了大量时间。如果他们不这样做,那么就没有必要担心他们。顺便说一句,我忘了提到在回调周围放置一个长循环的想法,这样你的停顿肯定会落在其中。然后在你加速之后,去掉循环,它就会飞起来。以上是关于如何分析音频回调的主要内容,如果未能解决你的问题,请参考以下文章