优化视频内存和系统内存之间的传输

时间:2015-03-25 15:38:46

标签: audio memory glsl gpu synthesizer

前段时间,我正在尝试使用GLSL在GPU上创建重型声音合成器。合成器能够在256多个同时发出的声音中产生非常复杂的声音。 在CPU上,我不敢梦想获得这种表现。

(简化说明)为了生成声音,我有一个NxV大小的浮点纹理。 N =样本数,V =语音数。合成着色器为每个纹素生成值。

然后,第二个着色器将所有声音混合在一起,形成16位有符号整数1D纹理(或声卡所需的任何格式)。使用像素缓冲区将最终纹理尽可能快地复制到系统内存,然后将其发送到声卡。

对于声音,我使用超低延迟的Windows Core Audio。

我写了一个MIDI接口,可以在连接到PC的midi键盘上播放,当使用英特尔GPU时,它的工作时间只有3毫秒(N = 132个样本,比所需的好很多) 15-20ms N = 600-900个样品)。但是当使用NVidia GPU能够支持更重的计算时,延迟要大得多(> 35ms N => 1500样本)。

据我所知,原因在于使用英特尔GPU时,渲染是直接在系统内存上进行的,并且复制该纹理非常快,但在使用NVidia GPU时,正在视频内存中进行渲染并从视频中复制内存到系统内存是一个瓶颈,即使它只有大约4KB的音频数据应该传输(它甚至不能达到硬件应该能够达到的6GB / s)。

有没有办法改善这个?例如,可以让NVidia GPU直接渲染系统内存(以可接受的速度),或者他们在OpenCL中谈论的那些着名的共享内存是什么? OpenCL会改善这个吗? (我没有使用OpenCL的经验)

1 个答案:

答案 0 :(得分:3)

有时,GPU写入主内存而不是CPU读取VRAM的速度更快。你这样做的方式是与公益组织,看看here。您必须提示将PBO存储在主存储器中。这可能有用也可能没用,取决于硬件架构。

OpenCL本身并不快。如果你在OpenGL中有一个干净的实现,你可能不会通过OpenCL实现获得速度提升。但是你可以在OpenCL中做一些你无法使用OpenGL的东西。

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

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

  2. 你转移的次数是否最少,你可以转移的次数最少。

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