sen*_*ruc 5 opengl macos opencl nsopenglview
我正在开发一个多GPU设置的OS X应用程序(Mac Pro 2013后期),它使用OpenCL(在辅助GPU上)生成纹理,然后使用OpenGL(在主GPU上)将其绘制到屏幕上.由于调用glBindTexture()和glBegin(),应用程序受CPU限制,两者都基本上花费了他们所有的时间:
_platform_memmove$VARIANT$Ivybridge
Run Code Online (Sandbox Code Playgroud)
这是视频驱动程序的一部分:
AMDRadeonX4000GLDriver
Run Code Online (Sandbox Code Playgroud)
设置:创建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);
Run Code Online (Sandbox Code Playgroud)
绘图代码:将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();
Run Code Online (Sandbox Code Playgroud)
在获得纹理内存的控制权之后(通过clEnqueueAcquireGLObjects()),OpenCL内核将数据写入纹理,然后释放对它的控制(通过clEnqueueReleaseGLObjects()).纹理数据永远不应该存在于主存储器中(如果我正确地理解了所有这些).
我的问题是:是否期望在memmove()中花费如此多的CPU时间?它是否表示我的代码存在问题?或许是驱动程序中的错误?我(毫无根据)的怀疑是纹理数据正在通过:GPUx - > CPU/RAM - > GPUy,我想避免.
在讨论内存传输之前,我的第一个观察是您正在使用 clBegin() ,它不会成为您最好的朋友,因为
1)这种直接绘图对于驱动程序来说效果不佳。请改用 VBO 等,以便该数据可以存在于 GPU 上。
2) 在 OS X 上,这意味着您处于旧的兼容性上下文中,而不是新的核心上下文中。据我了解,新的上下文是完全重写的,这就是未来优化的最终结果,而您正在使用的上下文(可能)只是被维护。
那么对于内存传输......在 GL 方面,您是否在其中放入 glCreateSyncFromCLeventARB() 和 glWaitSync() ?我在您的代码中看到应该不需要 glFlush() 。一旦您摆脱了立即模式绘制(如上所述)并在两个 API 之间使用同步对象,您的主机代码应该什么都不做(除了要求驱动程序告诉 GPU 做一些事情)。这将为您提供快速缓冲区复制的最佳机会......
是的,复制 :( 因为您的 CL 纹理实际上与 GL 纹理位于不同的 GPU 内存上,所以必须通过 PCIe 总线进行复制,这会很慢(呃)。这就是您在分析中看到的内容。实际发生的情况是,CPU 将 GPU 内存 A 和 GPU 内存 B 映射到固定主机内存,然后使用 DMA 在它们之间进行复制(希望如此)。我怀疑数据实际上触及系统内存,因此移动是 GPUx -> GPUy。
尝试将 CL 和 GL 上下文放在同一个 GPU 上,我想您会发现传输时间消失。
最后的想法:如果您的 CL 计算与传输时间相比显得相形见绌,那么最好将上下文放在同一个 CPU 上。您遇到了经典的 CPU/GPU 任务分割问题。
| 归档时间: |
|
| 查看次数: |
435 次 |
| 最近记录: |