3

前段时间,我尝试使用 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 的经验)

4

1 回答 1

3

有时,GPU 写入主存比 CPU 读取 VRAM 更快。你这样做的方式是使用 PBO,看看这里。您必须提示将 PBO 存储在主存储器中。这可能有用也可能没有帮助,并且取决于硬件架构。

OpenCL 并不是天生就更快。如果您在 OpenGL 中有一个干净的实现,那么您很可能不会通过 OpenCL 实现来提高速度。但是有些事情你可以在 OpenCL 中做而你不能用 OpenGL 做。

如果您仍然发现带宽是您的瓶颈,还有一些其他建议:

  1. 您是否尽可能多地避免阻塞?当您在线程中使用 GL 调用读取纹理时,您是否也在另一个线程中处理最后读取的纹理,就像这样。请注意,对 glGetTexImage 的调用是异步的,不会阻塞。只有在您调用 glMapBuffer 之前,您才会阻塞并知道传输已完成。

  2. 您是否转移了最少的转移次数、最少的转移次数。

  3. 有一些有损的压缩纹理格式,但可能适合您的需求?

于 2015-03-29T01:42:10.140 回答