0

我希望 arm mali midgard gpus 和 arm cpus 上的 opencl 缓冲区具有零复制行为,以便向量的数据指针和 clBuffer 在其生命周期内指向相同的位置。

我尝试过的一些事情。我为向量编写了一个自定义分配器(64 字节对齐),然后我尝试使用 cl_arm_import_memory 函数并将向量的指针传递给该函数。但问题是当我查询设备 EXT 属性时,我只看到 cl_arm_import_memory 字符串而不是 cl_arm_import_memory_host 字符串。

我还尝试先分配一个 gpu 端缓冲区,然后强制一个向量指向缓冲区的位置。但是根据 Mali guide ,gpu 端缓冲区的位置可能会发生变化,因此它可能会在多个映射期间指向不同的地址。

所以,我的问题是在 std::vector 和 OpenCL 缓冲区之间实现零复制行为的最佳方法是什么。

4

2 回答 2

1

我认为你混合了两个不相关的概念,零拷贝和共享虚拟内存。零拷贝并不能保证一块物理内存在 CPU 和 GPU 的同一地址上都是可见的——它们可以在 CPU 和 GPU 的虚拟地址空间中以不同的方式映射。如果希望物理内存在 GPU 和 CPU 中具有相同的虚拟地址,则需要共享虚拟内存 (SVM)。这需要 OpenCL 2.x 并通过clSVMAlloc(). 如果您的供应商仅提供 1.x 的 OpenCL 2.x,那么您就不走运了 - 您可以拥有零复制缓冲区,但不能拥有 SVM。

于 2019-10-21T10:47:29.037 回答
0

尝试这个:

  1. 使用 CL_MEM_ALLOC_HOST_PTR 创建缓冲区。
  2. 调用 clEnqueueMapBuffer 以获取主机端指针。

示例代码:

deviceBuffer = clCreateBuffer(cl->context,
                          CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
                          sizeof(T) * dataLength,
                          nullptr,
                          &error); checkError(error);

hostPtr = (T *) clEnqueueMapBuffer(cl->memCmdQueue,
                               zeroCopyMem.deviceBuffer,
                               CL_TRUE,
                               CL_MAP_WRITE,
                               0,
                               sizeof(T) * dataLength,
                               0, NULL, NULL, &error);
于 2020-01-14T09:27:58.323 回答