我正在多 GPU 设置(Mac Pro 2013 年末)中开发 OS X 应用程序,该应用程序使用 OpenCL(在辅助 GPU 上)生成纹理,该纹理随后使用 OpenGL(在主 GPU 上)绘制到屏幕上. 由于调用 glBindTexture() 和 glBegin(),该应用程序受 CPU 限制,这两者基本上都将所有时间都花在:
_platform_memmove$VARIANT$Ivybridge
这是视频驱动程序的一部分:
AMDRadeonX4000GLDriver
设置:创建 OpenGL 纹理 ( glPixelBuffer ),然后创建对应的 OpenCL ( clPixelBuffer )。
cl_int clerror = 0;
GLuint glPixelBuffer = 0;
cl_mem clPixelBuffer = 0;
glGenTextures(1, &glPixelBuffer);
glBindTexture(GL_TEXTURE_2D, glPixelBuffer);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2048, 2048, 0, GL_RGBA, GL_FLOAT, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
clPixelBuffer = clCreateFromGLTexture(_clShareGroupContext, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, glPixelBuffer, &clerror);
绘制代码:将 OpenGL 纹理映射到视口上。整个 NSOpenGLView 就是这一个纹理。
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, _glPixelBuffer); // <- spends cpu time here,
glBegin(GL_QUADS); // <- and here
glTexCoord2f(0., 0.); glVertex3f(-1.f, 1.f, 0.f);
glTexCoord2f(0., hr); glVertex3f(-1.f, -1.f, 0.f);
glTexCoord2f(wr, hr); glVertex3f( 1.f, -1.f, 0.f);
glTexCoord2f(wr, 0.); glVertex3f( 1.f, 1.f, 0.f);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glFlush();
在获得纹理内存的控制权(通过clEnqueueAcquireGLObjects())后,OpenCL 内核将数据写入纹理,然后释放对纹理的控制权(通过clEnqueueReleaseGLObjects())。纹理数据不应该存在于主内存中(如果我理解正确的话)。
我的问题是:预计会在 memmove() 中花费这么多 CPU 时间吗?这是否表明我的代码存在问题?或者驱动程序中的错误,也许?我的(毫无根据的)怀疑是纹理数据正在通过:GPUx -> CPU/RAM -> GPUy 移动,我想避免这种情况。