Я генерирую кадры в OpenCL 60 раз в секунду, используя каждый раз один вызов ядра OpenCL, и записываю их в текстуру OpenGL, чтобы я мог отобразить их на экране.Нет проблем с производительностью, частота кадров соответствует ожидаемой, однако проблема в том, что она очень расточительна, она полностью занята хотя бы одним ядром ЦП, даже когда ему мало что нужно сделать, например, вывести пустой кадр с очень низким разрешением,Для сравнения, когда я не использую взаимодействие OpenGL, а вместо этого записываю из ядра CL в общий буфер, а затем копирую этот буфер обратно на хост, чтобы затем отобразить его другим способом, частота кадров немного падает (из-заЧетвертая часть накладных расходов, которую взаимодействие делает ненужным), но тогда загрузка ЦП намного ниже, когда мало что сделать.
Это означает, что с тем, как я выполняю взаимодействие, что-то не так, что, как я полагаю, должно создать какую-то занятостьподождите.
Вот соответствующий код, который является кодом, который присутствует, когда я использую взаимодействие, и не существует, когда я его не использую.В одном месте моего цикла я очищаю текстуру GL и заставляю OpenCL получить ее:
uint32_t z = 0;
glClearTexImage(fb.gltex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &z);
glFlush();
glFinish();
clEnqueueAcquireGLObjects(fb.clctx.command_queue, 1, &fb.cl_srgb, 0, 0, NULL);
Затем я ставлю в очередь выполнение моего ядра OpenCL, которое записывает в текстуру как объект cl_mem
fb.cl_srgb
ипозже я возвращаю управление OpenGL, чтобы отобразить текстуру на дисплее:
clEnqueueReleaseGLObjects(fb.clctx.command_queue, 1, &fb.cl_srgb, 0, 0, NULL);
clFinish(fb.clctx.command_queue); // this blocks until the kernel is done writing to the texture and releasing the texture
// setting GL texture coordinates, probably not relevant to this question
float hoff = 2. * (fb.h - fb.maxdim.y) / (double) fb.maxdim.y;
glLoadIdentity(); // Reset the projection matrix
glViewport(0, 0, fb.maxdim.x, fb.maxdim.y);
glBegin(GL_QUADS);
glTexCoord2f(0.f, 0.f); glVertex2f(-1., 1.+hoff);
glTexCoord2f(1.f, 0.f); glVertex2f(1., 1.+hoff);
glTexCoord2f(1.f, 1.f); glVertex2f(1., -1.+hoff);
glTexCoord2f(0.f, 1.f); glVertex2f(-1., -1.+hoff);
glEnd();
SDL_GL_SwapWindow(fb.window);
Мне трудно сказать, что является причиной этого, поскольку высокая загрузка ЦП находится в другом потоке, выполняемом nvopencl64.dll(когда я запускаю его на своем компьютере с Windows 10 с графическим процессором nVidia, но у меня похожая проблема с ноутбуком с Intel iGPU, также на Windows 10).
Профилирование говорит мне, что большая часть времени процессораWaitForSingleObjectEx
(исключая 42% процессорного времени) вызывается из nvopencl64.dll, WaitForMultipleObjects
(21%) вызывается из DrvPresentBuffers
nvoglv64.dll и RtlUserThreadStart
(16%) вызовов, которые инициируют вышеупомянутыеWaitForMultipleObjects
звонки.Это для моей машины с графическим процессором nVidia, но ситуация выглядит довольно похоже на машине с Intel HD 5000 iGPU.Очевидно, что происходит что-то очень неэффективное, возможно, слишком много потоков запускается слишком часто.