1

我有一种情况,我(可能)想尝试使用 a std::vector(或更准确地说是它的存储)作为buffer带有CL_MEM_USE_HOST_PTR. vector如果调整大小并因此重新分配其内存,这显然会出现问题。对 my 的修改vector是在程序的阶段,buffer没有使用,所以我的想法是检查缓冲区的主机指针是否与指向第一个元素的指针相同,vector如果不是则重新创建缓冲区案子。我的问题是我无法确定拥有 a 是否合法,如果未使用buffer主机指针已被释放的主机指针。buffer

我当然可以在使用它的阶段结束时销毁缓冲区,但是我事先不知道向量内容和/或长度是否被修改,如果不是,我宁愿保留旧缓冲区,因为 afaik 可以让它保持缓存在设备上,从而减少需要通过 pci-e 总线传输的数据量。

我的问题是:如果该对象仅存在但未在内核中使用,是否允许buffer使用CL_MEM_USE_HOST_PTR其主机指针已经删除主机指针的opencl。buffer

作为记录,我目前正在针对 nvidias opencl 实现进行开发,使用 Tesla 2070 作为 gpu,并且该软件可能会在不久的将来移植到 amd gpus/cpus(后者是使用的主要原因CL_MEM_USE_HOST_PTR)。因此,如果答案是特定于实现的,那么这些是主要目标,尽管我对一般答案更感兴趣,因为我不知道以后还会运行什么。

4

2 回答 2

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);

当内存被释放时,它将尝试将数据同步回原始缓冲区(已被释放),这可能会导致段错误或其他一些令人讨厌的内存问题。

根据关于这个线程的一些讨论,应该假设一旦您使用CL_MEM_USE_HOST_PTR标志调用 clCreateBuffer,您已经将该内存的控制权交给 OpenCL 平台,并且您只能通过调用释放该内存缓冲区来回收该内存。 .

虽然在您的具体实施中可能并非如此,但我认为总体而言,建议发布数据。这样,如果您的底层系统将来发生变化,您将不会看到与此行为相关的错误。

或者,您可以扩展向量类,以便在调整基础数据结构的大小时,您可以在设备上释放和重新分配数据。不过,我不确定这会有多困难,或者它会影响你程序的其余部分。

于 2012-10-09T17:20:42.813 回答
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 设备),那么内核很可能会在执行时崩溃或提供垃圾结果(基于其中的内容)现在的位置)。

希望这可以帮助!

于 2012-10-09T16:13:45.630 回答