前段时间,我尝试使用 GLSL 在 GPU 上创建重型声音合成器。该合成器能够同时生成超过 256 种以上的非常复杂的声音。在 CPU 上,我做梦也不敢想能得到这样的性能。
(简化解释)为了生成声音,我有一个 NxV 大小的浮点纹理。N = 样本数,V = 声音数。合成着色器为每个纹素生成值。
然后,第二个着色器将所有声音混合到一个 16 位有符号整数 1D 纹理(或声卡所需的任何格式)中。这个最终的纹理使用像素缓冲区尽可能快地复制到系统内存,然后将其发送到声卡。
对于声音,我使用超低延迟的 Windows Core Audio。
我编写了一个 MIDI 接口,以便能够在连接到 PC 的 MIDI 键盘上播放,并且在使用延迟仅为 3 毫秒的英特尔 GPU 时它可以完美运行(N = 132 个样本,这比所需的 15-20 毫秒要好得多N = 600-900 个样本)。但是当使用 NVidia GPU 能够支持更繁重的计算时,延迟要大得多(>35ms N=>1500 个样本)。
我知道原因是当使用 Intel GPU 时,渲染是直接在系统内存上完成的,并且复制该纹理非常快,但是当使用 NVidia GPU 时,渲染是在显存中完成并从显存复制到系统内存是一个瓶颈,即使它只应该传输大约 4KB 的音频数据(这甚至没有接近硬件应该能够达到的 6GB/s)。
有没有办法改善这一点?例如,是否可以让 NVidia GPU 直接渲染到系统内存(以可接受的速度),或者他们在 OpenCL 中谈论的那些著名的共享内存是什么?OpenCL 会改善这一点吗?(我没有使用 OpenCL 的经验)