我有一种情况,我可能想尝试使用std::vector
(或者更确切地说是它的存储)作为具有buffer
的opencl CL_MEM_USE_HOST_PTR
对象的主机指针。如果vector
被调整大小并因此重新分配其内存,这显然存在问题。对vector
的修改是在程序的各个阶段,其中buffer
未使用,所以我的想法是检查缓冲区的主机指针是否与指向第一个元素的指针相同如果不是这样的话vector
并重新创建缓冲区。我的问题是,如果没有使用buffer
,我无法确定是否已经取消分配主机指针buffer
是否合法。< / p>
我当然可以在使用它的阶段结束时销毁缓冲区,但是事先我不知道是否修改了向量内容和/或长度,如果它们不是,我宁愿保留旧的缓冲区,因为afaik可以使它保持缓存在设备上,减少了需要通过pci-e总线传输的数据量。
我的问题是:如果buffer
允许主机指针已经删除主机指针的CL_MEM_USE_HOST_PTR
,那么它是否允许使用buffer
object只存在,但没有在内核中使用。
我正在开发针对nvidias opencl实现的记录,使用特斯拉2070作为gpu,软件可能会在不久的将来被移植到amd gpus / cpus(后者是使用{{的主要原因} 1}})。因此,如果答案是特定于实现的,那么这些是主要目标,尽管我对一般答案更感兴趣,因为我不知道它将在以后运行什么。
答案 0 :(得分:1)
我相信如果您不尝试更改OpenCL实现下的缓冲区会更安全。如你所说,这可能会带来问题。例如:
vector<int> v(25);
cl_mem buf = clCreateBuffer(.v.data(),.CL_MEM_USE_HOST_PTR,...);
v.resize(1000); //Or some other way of changing the size of the stack
clReleaseMemObject(buf);
当内存被释放时,它将尝试将数据同步回原始缓冲区(已被解除分配),可能导致段错误或其他一些令人讨厌的内存问题。
根据对this thread的一些讨论,应该假设一旦你用CL_MEM_USE_HOST_PTR
标志调用clCreateBuffer,你就已经控制了那个内存到OpenCL平台,你只能这样做通过调用释放该内存缓冲区来回收该内存。
虽然在您的具体实施中可能并非如此,但我认为总体而言,最好是发布数据。这样,如果您的基础系统将来发生变化,您将看不到与此行为相关的错误。
可选地,您可以扩展向量类,以便在基础数据结构的大小调整时,您可以在设备上释放和重新分配数据。我不确定这会有多困难,或者它会对你的其他程序有多大影响。
答案 1 :(得分:0)
您的问题的答案取决于用于创建缓冲区的标志。如果使用CL_MEM_ALLOC_HOST_PTR或CL_MEM_COPY_HOST_PTR调用clCreateBuffer,则OpenCL实现已经有一个副本(在CL_MEM_ALLOC_HOST_PTR的情况下,可能 - 应该用于GPU实现)您提供的主机位置的内容。现在,您可以随心所欲地使用该主机指针执行任何操作,而OpenCL实现并不关心。
另一方面,如果你使用CL_MEM_USE_HOST_PTR(我不认为你这样做,或者甚至因为这是GPU设备),那么内核很可能会在执行时崩溃或提供垃圾结果(基于那个位置现在是什么。)
希望这有帮助!