OpenCL — производительность взаимодействия OpenGL

У меня есть код, в котором я создаю текстуру GL 8K (7680 x 4320) и визуализирую эту текстуру. Затем я переключаю его на CL и делаю кое-что...

Проблема в том, что "переключение" происходит очень медленно.

Если я не запускаю код CL, только переключаюсь. На моей GTS 450 около 40 кадров в секунду.

Если я прокомментирую строку «clEnqueueAcquireGLObjects(..)» => нет переключения. Он имеет около 600FPS.

Есть ли способ, как я могу ускорить?

Я тоже хочу спросить, если это проблема только с Nvidia или другими, такими как Ati, Intel и некоторые SoC (ARM), имеют одинаковую проблему со скоростью?

Создание текстуры GL-CL:

glGenFramebuffers(1, &m_fbo);
glGenTextures(1, &m_tex);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
glBindTexture(GL_TEXTURE_2D, m_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_imageSize.x, m_imageSize.y, 0, GL_RGBA, GL_INT, NULL);        //GL_ALPHA
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_tex, 0);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE)
    return false;
glBindFramebuffer(GL_FRAMEBUFFER, 0);

int err;
m_memD = clCreateFromGLTexture2D(ecl.getContext(), CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0, m_tex, &err);
if(ERR_CL)
    return false;

GL - CL Взаимодействие:

void activateCL()
{
    glFinish();
    int err = clEnqueueAcquireGLObjects(m_queue, 1, &m_memD, 0, 0, 0);
}    
void activateGL()
{
    int err;
    err = clFinish(m_queue);
    err = clEnqueueReleaseGLObjects(m_queue, 1, &m_memD, 0, 0, 0);

}

bool activateGLRendering()
{
    activateGL();
    glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
    return true;
}
bool deactivateGLRendering()
{
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    return true;
}

person Milan    schedule 27.07.2013    source источник


Ответы (2)


Тот же вопрос, что и в этой теме: ССЫЛКА

Проблема только в драйвере nVIDIA + Windows. Не АМД, не Интел и не линукс. Но, как говорится в комментарии @user2725937:

It is reported to nVIDIA and fixed in 331.xx beta drivers
person DarkZeros    schedule 17.10.2013

На вашей платформе здесь могут не потребоваться glFinish и clFinish. Вместо этого попробуйте использовать glFlush и clFlush.

Это действительно зависит от платформы, как указано в спецификациях расширения CL/GL. В спецификациях говорится, что Finish — единственный полностью переносимый способ, но могут существовать и более быстрые альтернативы.

Например, в Mac OS X вам нужно только glFlushRenderAPPLE и не нужно clEnqueueAcquireGLObjects при переключении с GL на CL, а затем только clFlush и не нужно >clEnqueueReleaseGLObjects при переключении обратно на GL.

person Eric Bainville    schedule 27.07.2013
comment
Как насчет того, чтобы не делать ни того, ни другого и использовать объект синхронизации? - person Nicol Bolas; 27.07.2013
comment
Я только что попробовал сбросить, и это то же самое :( Медленные вещи происходят в clEnqueueAcquireGLObjects() и clEnqueueReleaseGLObjects(). Finish или Flush не проблема! - person Milan; 27.07.2013
comment
Никол: Но если я использую Sync Object. Я все еще должен вызвать clEnqueueAcquireGLObjects(), поэтому я думаю, что это не решение :( - person Milan; 27.07.2013
comment
@Milan: Эрик и Никол пытаются подчеркнуть, что и glFinish, и clFinish, как известно, работают медленно, поскольку вызывают полную остановку. Таким образом, вы явно делаете свой GPU полностью бездействующим дважды за кадр. - person Damon; 27.07.2013
comment
glFinish и clFinish необходимы. opencl должен завершиться до того, как opengl вступит во владение, и наоборот (clFlush гарантирует только то, что команды выдаются незавершенными). Некоторое время назад я сделал небольшую программу, используя ocl и ogl (используя clFinish и glFinish), даже с работающим ядром я мог достигать около 500 кадров в секунду на GTX660Ti. Так что я почти уверен, что проблема где-то в другом. - person CaptainObvious; 27.07.2013
comment
40 кадров в секунду для разрешения 8K, в Full HD он работает около 450 кадров в секунду. - person Milan; 28.07.2013
comment
CaptainObvious: Вы использовали буфер кадров? Мне нужно отрендерить текстуру, а затем применить постобработку в CL. - person Milan; 28.07.2013
comment
Проблема не в cl/glFinish() — они быстрые. Медленно работают clEnqueueAcquireGLObjects() и clEnqueueReleaseGLObjects() !!! - person Milan; 28.07.2013
comment
@Eric Bainville: хорошая информация о спецификациях, в которых говорится, что clFinish - единственный полностью переносимый способ. Я упустил из виду эту часть. Спасибо. - person CaptainObvious; 30.07.2013
comment
У меня была аналогичная проблема, когда я пытался научиться использовать OpenCL пару лет назад на карте ATI. Я сдался и решил, что OpenCL непригоден для использования. С тех пор я попробовал CUDA на карте NVidia и получил гораздо лучшие результаты. Тогда мне интересно, есть ли разница в производителях, поскольку драйверы ATI, как правило, плохие. Какой тип карты у вас есть? - person Joe; 30.07.2013
comment
Джо: Nvidia GTS 450 (Fermi). Может быть, Кеплер лучше. Самая большая проблема в том, что я могу сделать некоторую оптимизацию, но это дурацкое взаимодействие GL/CL убивает все! - person Milan; 31.07.2013