Audio 优化视频存储器和系统存储器之间的传输

Audio 优化视频存储器和系统存储器之间的传输,audio,memory,glsl,gpu,synthesizer,Audio,Memory,Glsl,Gpu,Synthesizer,不久前,我正在试验使用GLSL在GPU上创建一个重型声音合成器。synth能够在256+个同时发出的声音中产生非常复杂的声音。 在CPU上,我不敢梦想获得这样的性能 (简化解释)为了产生声音,我有一个NxV大小的浮点纹理。N=采样数,V=语音数。synth着色器为每个纹理生成值 然后,第二个着色器将以16位有符号整数1D纹理(或声卡所需的任何格式)将所有声音混合在一起。使用像素缓冲区将最终纹理尽可能快地复制到系统内存中,然后将其发送到声卡 对于声音,我使用超低延迟Windows核心音频 我编写了

不久前,我正在试验使用GLSL在GPU上创建一个重型声音合成器。synth能够在256+个同时发出的声音中产生非常复杂的声音。 在CPU上,我不敢梦想获得这样的性能

(简化解释)为了产生声音,我有一个NxV大小的浮点纹理。N=采样数,V=语音数。synth着色器为每个纹理生成值

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

对于声音,我使用超低延迟Windows核心音频

我编写了一个MIDI接口,可以在连接到PC的MIDI键盘上播放,当使用英特尔GPU时,它的延迟仅为3ms(N=132个样本,比所需的15-20ms N=600-900个样本好得多)。但是当使用英伟达GPU能够支持更重的计算时,延迟要大得多(>35MS n=> 1500个样本)。 <>我理解,原因是当使用英特尔GPU时,渲染直接在系统内存上进行,复制纹理非常快,但是当使用英伟达GPU时,在视频存储器中进行渲染,从视频存储器复制到系统内存是一个瓶颈,即使只需要传输大约4KB的音频数据(硬件所能传输的音频数据甚至还不到6GB/s)


有没有办法改善这一点?例如,英伟达GPU可以直接渲染TOT系统内存(以可接受的速度),或者在OpenCL中讨论的那些共享的共享内存是什么?OpenCL会改进这一点吗?(我没有使用OpenCL的经验)

有时,GPU写入主存比CPU读取VRAM更快。这样做的方式是使用PBO,请看一看。您必须提示将PBO存储在主内存中。这可能有帮助,也可能没有帮助,取决于硬件体系结构

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

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

  • 您是否尽可能避免阻塞?当您在一个线程中通过GL调用读取纹理时,您是否也在另一个线程中处理上次读取的纹理,类似这样的事情。请注意,对glGetTexImage的调用是异步的,不会阻塞。只有在调用glMapBuffer之前,您才会阻塞并知道传输已完成

  • 你是在尽可能少的转移,最少的转移次数吗

  • 有一些压缩纹理格式是有损的,但可能适合您的需要


  • 你能告诉我关于你说的第一件事的更多信息吗:让GPU写入主内存?我有两个交换帧缓冲区,其中包含纹理,GPU在其中渲染声音数据。我使用PBO将帧缓冲区数据复制到系统内存中。我不明白如何更改PBO以使GPU存储在系统内存中。我是否需要立即渲染到PBO而不是纹理?有这样的例子吗?至于你的建议:1。我想我是在避免所有可能的阻塞:系统的设计使得当请求声音缓冲时,它应该已经用PBO传输了(这似乎是个问题)。2.是的,我想是的。3.我理解,但数据已经非常小,我认为瓶颈更多的是传输的启动,而不是传输本身。这就是为什么我非常渴望了解如何直接渲染到系统内存的原因。@scipie请参阅,有关设置GPU写入主内存的更多信息,请参阅,这只是一个提示,可能有用,也可能没有帮助。请注意,对glGetTexImage的调用是异步的,不会阻塞。只有在调用glMapBuffer之前,您才会阻塞并知道传输已完成。谢谢,我知道所有这些,并且我已经使用了它,除了READ_STREAM提示。出于某种原因,我使用了WRITE_DYNAMIC。我不记得为什么了。我以后再试试。可惜这只是一个提示,驾驶员可能会选择其他方式。它永远不会给我任何确定性。