首先,一些相关的背景信息:我有一个基于CoreAudio的低延迟音频处理应用程序,它可以对来自专用Mac(运行最新版本的MacOS(上输入设备的音频进行各种混合和特殊效果,并将结果返回到Mac的一个本地音频设备。
为了获得最佳/最可靠的低延迟性能,该应用程序被设计为挂接CoreAudio的低级别音频呈现回调(通过AudioDeviceCreateIOProcID((、AudioDeviceStart((等(,每次调用回调函数(从CoreAudio's实时上下文(时,它都会读取传入的音频帧(例如128帧,每帧64个样本(,进行必要的计算,并写出输出样本。
这一切都很好,但从我读到的所有内容来看,苹果的CoreAudio实现有一个不成文的事实要求,即所有实时音频操作都发生在一个线程中。我承认这是有充分理由的(主要是除了我已经使用的SIMD/SSE/AVX指令之外,几乎所有用于协调并行行为的机制都不是实时安全的,因此尝试使用它们会导致间歇性的音频故障(。
然而,我和我的同事都很贪婪,尽管如此,我们还是想对每个样本缓冲区进行比最快的单核在短时间窗口内可靠执行的数学运算多得多的运算,这是避免音频不足和故障所必需的。
我的同事(在嵌入式/专用Linux硬件上的实时音频处理方面经验丰富(告诉我,在Linux下,程序可以请求对一个或多个CPU内核的独占访问,这样操作系统就永远不会试图将它们用于其他用途。一旦他做到了这一点,他就可以运行";裸金属";简单地忙于等待/轮询原子变量的CPU上的样式代码;真实的";音频线程更新它,让专用核心知道是时候做自己的事情了;在这一点上,专用核心将在输入样本上运行其数学例程并在(希望(有限的时间内生成其输出;真实的";音频线程可以收集结果(这里更忙的是等待/轮询(,并将它们合并回传出的音频缓冲区。
我的问题是,这种方法值得在MacOS/X下尝试吗?(即,一个MacOS/X程序,即使是一个具有root访问权限的程序,能否说服MacOS授予它对某些内核的独占访问权限?如果是这样,这些内核上的大而丑陋的繁忙等待/轮询循环(包括相对于其输入/输出要求同步CoreAudio回调线程所需的轮询循环(是否会产生可靠实时的结果,让你有朝一日可能想要使用它们在付费观众面前?(
原则上这似乎是可能的,但在我花太多时间把头撞向那里可能存在的任何墙壁之前,我想谈谈这是否是一条值得在这个平台上追求的途径。
一个MacOS/X程序,即使是一个具有root访问权限的程序,也能说服MacOS授予它对某些核心的独占访问权限吗
我不知道这一点,但您可以使用任意数量的核心/实时线程进行计算,使用使其工作所需的任何同步方法,然后使用无锁环形缓冲区(如TPCircularBuffer(将音频传递到IOProc
。
但你的问题让我想起了我一直想尝试的新macOS 11/iOS 14 API,Audio Workgroups API(2020 WWDC视频(。
我的理解是,这个API让你";祝福";您的非IOProc实时线程具有音频实时线程属性,或者至少与音频线程更好地协作。
文档区分了并行工作的线程(这听起来像你的情况(和异步工作的线程,我不知道哪种情况更适合你。
我仍然不知道当你使用Audio Workgroups
时,在实践中会发生什么,他们是选择你接受好的东西还是选择你不接受坏的东西,但如果他们不是你想要的锤子,他们可能有一些有用的类似锤子的特性。