OpenCL主机复制性能警告



我有一个OpenCL程序,可以在共享上下文中调整VBO对象的顶点坐标。OpenCL设备是一个GPU设备。

然而,我收到以下警告:

缓冲区性能警告:缓冲区对象1(绑定到GL_VERTEX_ATTRIB_ARRAY_Buffer_BINDING_ARB(0)、GL_VERTEX _ATTRIY_Buffer _BINDING-ARB(4)和GL_ARRAY_Buffer_ARB,使用提示为GL_DYNAMIC_DRAW)正在从VIDEO内存复制/移动到HOST内存。

据我所知(必须添加一些glFlush()调用来提供帮助),这发生在对glDrawElements(...)的调用期间。着色器位置0处的顶点属性数组是顶点,着色器位置4处的顶点内容数组是纹理坐标。

问题是,为什么会出现这种情况?

EDIT:循环的形式如下:

glFinish()
clEnqueueAcquireGLObjects(...)
clEnqueueNDRangeKernel(...)
clFinish(...)
clEnqueueReleaseGLObjects(...)

因为在OpenGL支持VBO之前,对glDrawElements (...)的每次调用都会立即从客户端提取内存(而不是GPU开始执行命令时)。GL在后台排队命令,但对于某些操作,它必须阻止和/或复制数据,以防止并发处理器(在这种情况下是CPU或OpenCL)在OpenGL实际完成命令之前修改数据。它需要实际调用glDrawElements (...)时存在的数据的副本。

VBO通过让OpenGL服务器显式控制对顶点内存的所有访问,解决了这个基本问题。不再可能以OpenGL服务器不知道的方式同时修改顶点内存。任何修改顶点内存的尝试都需要GL管道中的命令,因此确保排队的命令具有顶点数据的正确副本可以完全由GL自己管理,而无需进行不必要的复制或阻止。

当您在GL和CL之间共享缓冲区对象时,您实际上打破了GL中缓冲区对象的一些美妙之处。它为GL拥有的内存提供了一个单独的并发管道访问,因此GL无法再确定在不知情的情况下没有任何东西修改其拥有的数据。

clEnqueueAcquireGLObjects

获取已从OpenGL对象创建的OpenCL内存对象。

[…]

备注

在调用clEnqueueAcquireGLObjects之前,应用程序必须确保访问mem_objects中指定对象的任何挂起的GL操作都已完成。这可以通过在所有具有对这些对象的挂起引用的GL上下文上发出并等待完成glFinish命令来实现。实现方式可以提供更有效的同步方法;例如,在一些平台上,调用glFlush可能就足够了,或者同步可能隐含在线程中,或者可能存在供应商特定的扩展,这些扩展允许在GL命令流中放置围栏并等待CL命令队列中完成该围栏。请注意,目前除了glFinish之外,没有其他同步方法可以在OpenGL实现之间移植。

类似地,在调用clEnqueueReleaseGLObjects之后,应用程序负责确保在执行引用这些对象的后续GL命令之前,访问mem_objects中指定对象的任何挂起的OpenCL操作都已完成。这可以通过使用clEnqueueReleaseGLObjects返回的事件对象调用clWaitForEvents或通过调用glFinish来实现。如上所述,一些实现可以提供更有效的方法。

您需要GL/CL同步来正确处理此问题,这就解释了glFlush (...)有帮助的原因。但是,刷新命令队列通常是不够的。这只是告诉德国劳埃德船级社立即开始处理其缓冲的所有命令,但甚至不试图确保它们在控制权返回CPU之前完成

要完全回答这个问题,需要更多的细节;特别是使用缓冲区数据的CL和GL命令的序列以及您正在使用的同步

最新更新