OpenGL PBO映射的缓冲区:多线程解压缩速度慢,内存恢复速度快

时间:2018-08-29 08:20:11

标签: multithreading opengl directx amd

我们正在使用Core i7和AMD FirePro 8000工作站。对于视频解码(8K,7680x4320视频帧〜66MB hapq编解码器),我们尝试使用以下明显的循环:

  1. 从流中获取帧
  2. 地图缓冲区
  3. 将多帧解码帧切片解码到映射缓冲区中
  4. 取消映射缓冲区
  5. texsubimage从绑定的PBO变成纹理

但要走一步 3。将多线程切片解码为映射缓冲区 太慢了-至少需要40毫秒才能完成

当我们将其分为两个步骤

3a。将多线程的帧片解码到分配的内存中

3b。从分配的内存中的memcpy到映射的缓冲区

两个步骤都需要8 + 9〜17ms才能完成。现在我们有了一个可以接受的解决方案,但是额外的复制步骤很痛苦。

为什么多线程解压缩到映射内存的速度如此之慢?我们如何避免多余的复制步骤?

编辑1;

这是生成,定义和映射缓冲区的方式:

glGenBuffers(1, &hdf.m_pbo_id);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, hdf.m_pbo_id);
glBufferData(GL_PIXEL_UNPACK_BUFFER, m_compsize, nullptr, GL_STREAM_DRAW);
hdf.mapped_buffer = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);

编辑2:

有人提出了一个如何测量时间的问题。仅测量非GL代码。伪代码是这样的,

案例1(非常慢,t2-t1〜40ms):

gl_map();
t1 = elapse_time();
unpack_multithreaded_multiple_snappy_slices_into_mapped_buffer();
t2 = elapse_time();
gl_unmap();

第2种情况(中等速度,t3-t2〜9ms,t2-t1〜8ms):

gl_map();
malloc_sys_buffer();
t1 = elapse_time();
unpack_multithreaded_multiple_snappy_slices_into_sys_buffer();
t2 = elapse_time();
memcpy_sys_buffer_into_mapped_buffer();
t3 = elapse_time();
gl_unmap();

在所测量的代码块中,没有涉及OpenGL代码。也许这是一个直写/ cpu-cache问题。

1 个答案:

答案 0 :(得分:0)

解压缩到映射的内存很慢,因为该内存是写合并的。对于这种类型的内存的每次写入,整个高速缓存行都会通过总线传输到GPU。与该内存进行交互的最佳方法是尽可能大地写入数据。为了避免额外的复制步骤,您可能需要修改解码器以写入大块连续的内存。尝试编写线程的数量也很好。 https://fgiesen.wordpress.com/2013/01/29/write-combining-is-not-your-friend/

对此有很好的概述