Отображаемый буфер OpenGL PBO: многопоточная распаковка медленная, memcpy быстрая - PullRequest
0 голосов
/ 29 августа 2018

Мы работаем на рабочей станции Core i7 и AMD FirePro 8000. Для декодирования видео (8K, видеокадр 7680x4320 ~ кодек hapq 66 МБ) мы попытались использовать следующий очевидный цикл:

  1. получить кадр из потока
  2. буфер карты
  3. декодировать фрагменты кадра многопоточно в отображенный буфер
  4. unmap buffer
  5. texsubimage в текстуру из связанных PBO

НО шаг 3. декодировать фрагменты многопоточно в отображенный буфер ужасно медленный - для завершения требуется не менее 40 мс

Когда мы разбиваем это на шаги буксировки

3a. декодировать фрагменты кадра многопоточно в малую память

3b. memcpy из ошибочной памяти в отображенный буфер

для завершения обоих шагов требуется 8 + 9 ~ 17 мс. Теперь у нас есть несколько приемлемое решение, но дополнительный шаг копирования является болезненным.

Почему многопоточная распаковка в отображенную память так медлительна? Как мы можем избежать дополнительного шага копирования?

Редактировать 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:

Был задан вопрос, как измеряется время. Только non-gl код измеряется. Псевдокод такой,

Случай 1 (очень медленный, t2-t1 ~ 40 мс):

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

Случай 2 (средняя медленная, t3-t2 ~ 9 мс, t2-t1 ~ 8 мс):

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.

...