Мы работаем на рабочей станции Core i7 и AMD FirePro 8000. Для декодирования видео (8K, видеокадр 7680x4320 ~ кодек hapq 66 МБ) мы попытались использовать следующий очевидный цикл:
- получить кадр из потока
- буфер карты
- декодировать фрагменты кадра многопоточно в отображенный буфер
- unmap buffer
- 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.