【问题标题】:Transfer data from Mat/oclMat to cl_mem (OpenCV + OpenCL)将数据从 Mat/oclMat 传输到 cl_mem (OpenCV + OpenCL)
【发布时间】:2014-02-16 20:37:07
【问题描述】:

我正在做一个需要大量 OpenCL 代码的项目。我正在使用 OpenCV 的 ocl 模块来更快地开发我的项目,但是有一些功能没有实现,我将不得不编写自己的 OpenCL 代码。

我的问题是:将数据从 Mat 和/或 oclMat 传输到 cl_mem 数组的最快和最便宜的方法是什么。重新措辞一下,有没有一种好方法可以从 oclMat 或 Mat 传输或入队(clEnqueueWriteBuffer)数据?

目前,我正在使用 for 循环从 Mat 读取数据(或从 oclMat 下载,然后使用 for 循环),然后将其入队。事实证明这是昂贵的,因此我的问题。

感谢任何看到这个问题的人:)

【问题讨论】:

  • 嗨,这对我有用。假设 x 是一个用“1”初始化的 oclMat。 oclMat x(100, 100, CV_32FC1, 标量 (1)); clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&x.data);这对我有用,我通过挖掘 OpenCV 中给出的 ocl 代码得到了这个想法。如果您认为这里可能出现问题,请告诉我。谢谢!!
  • 这是正确的使用方法。您甚至没有使用另一个缓冲区,而是直接使用原始 oclMat 缓冲区。当您将其缓冲区用于其他目的时,请注意不要使用原始 oclMat。

标签: opencv opencl


【解决方案1】:

对于您的评论,这是正确的。 oclMat 可以用作设备的 cl_mem(void *),因为它是由 OpenCL 设备分配的。

此外,您可以先创建 svm 内存(例如 void* svmdata),然后分配一个 Mat,如:Mat A(rows, cols, CV_32FC1, svmdata)。 现在您可以在主机和设备之间处理 Mat A 而无需内存复制。 (PS.svm内存是OCL的新特性,可以通过clSVMAlloc创建)。

【讨论】:

    【解决方案2】:

    我为Boost.Compute 库编写了一组互操作函数,这些函数简化了OpenCL 和OpenCV 的使用。看看opencv_copy_mat_to_buffer() 函数。

    还有从 OpenCL 缓冲区复制回主机 cv::Mat 以及将 cv::Mat 复制到 OpenCL image2d 对象的函数。

    【讨论】:

      【解决方案3】:

      oclMat 的文档指出底层 ocl 缓冲区数据具有某种功能:

      //! pointer to the data(OCL memory object)
      uchar *data;
      

      如果您的设备中已经有 clMat,您可以简单地从clMat.data 复制缓冲区到您的clBuffer。但是你将不得不破解一点内存,访问 oclMat 的一些私有成员

      类似:

      clEnqueueCopyBuffer(command_queue, (clBuffer *)oclMat.data, dst_buffer, 0, 0, size);
      

      注意:请注意转换,也许您必须转换另一个指针。

      【讨论】:

      • 感谢您的回答和时间!其他东西对我有用——请查看我对原始问题的评论。
      【解决方案4】:

      计算内存带宽,在主机-设备互连中实现。

      如果您获得最大带宽的约 60% 或更多,您将无事可做,内存传输将尽可能快。但是,如果您的带宽结果低于理论最大值的 55% - 60%,请尝试使用具有解锁操作的多个命令队列(不要忘记最后同步)。另外,请注意平均图像大小。小数据传输通常有很大的开销率。

      如果您的设备使用共享内存,请使用内存映射而不是读/写,这可能会大大节省时间。如果设备有自己的内存,请应用固定内存技术,这在 NVIDIA OpenCL 最佳实践指南中有很好的描述。

      【讨论】:

      • 感谢您的回答和时间!其他东西对我有用——请查看我对原始问题的评论。
      • 使用适当的构造函数意味着复制在后台进行。我假设 CL_MEM_COPY_HOST_PTR 标志在内存对象创建阶段使用。不过,如果您对解决方案感到满意,那很好:)
      猜你喜欢
      • 1970-01-01
      • 2015-10-04
      • 2013-06-19
      • 1970-01-01
      • 2019-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-23
      相关资源
      最近更新 更多