【问题标题】:Advice to chain several CUDA operations in openCV?在 openCV 中链接多个 CUDA 操作的建议?
【发布时间】:2022-06-30 16:52:37
【问题描述】:

我想:

  1. 将数据上传到 CUDA 世界
  2. 执行多个 CUDA 操作(gemm、阈值、dft 等)
  3. 将结果下载到 CPU 世界

如何以最佳方式优化 CUDA 块部分 有没有办法调用.cu代码?

这是我正在做的一个例子

cv::cuda::GpuMat _emptyGpuMat;
cv::cuda::GpuMat _resultGPU;
cv::cuda::Stream GPUstream;

// -----------------------------
// Upload CPU data to the GPU
// -----------------------------
_mat1GPU.upload(_mat1);
_mat2GPU.upload(_mat2);
const auto _startTimeGPU = std::chrono::high_resolution_clock::now();
    
// to show several things done in a block of CUDA operations
{
    cv::cuda::gemm(_mat1GPU, _mat2GPU, 1.0, _emptyGpuMat, 0.0, _resultGPU,0, GPUstream);
    cv::cuda::threshold(_mat2GPU, _mat2GPU, .01, std::numeric_limits<double>::max(), cv::THRESH_TOZERO);
}

GPUstream.waitForCompletion();

// -----------------------------
// Download GPU data to the CPU
// -----------------------------
cv::Mat _matResult;
_resultGPU.download(_matResult);
(void)_matResult;

// ---------------------------------------------------------------
// Deallocate data here, otherwise deallocation will be performed
// after context is extracted from the stack
// ---------------------------------------------------------------
_mat1GPU.release();
_mat2GPU.release();
_resultGPU.release();

【问题讨论】:

    标签: c++ opencv cuda


    【解决方案1】:

    恕我直言,您以正确的方式做事。 OpenCV 开发人员在内部将 cuBLAS 用于 gemm,除非您搜索几微秒,否则无需搜索如何直接调用内核。

    我会添加一两件事,

    1. 我观察到对 gpu 代码的第一次调用比下一次调用的时间长(可能是由于初始化开销),我通常先执行一两个操作以让 opencv 正确初始化,然后才对我的代码进行基准测试。
    2. 使用流时,不要忘记在每次调用时都使用它们(阈值操作中缺​​少流),以确保操作的执行顺序正确。在将数据复制到 GPU 内存时,您还可以使用 cv::Stream。
    3. 如果您对性能有任何疑问,可以使用 nsight 系统对您的代码进行基准测试,并确保操作在同一流中执行,并且没有不必要的同步。 (更多信息请参见NSight system

    如果你真的很热衷于表现并且需要这几微秒,也许你可以尝试直接查看NVidia Performance primitivecublas,看看这是否可以提高性能,但我对此表示怀疑。

    【讨论】:

      猜你喜欢
      • 2018-07-15
      • 2020-08-14
      • 1970-01-01
      • 2013-05-23
      • 2019-04-09
      • 2010-10-22
      • 2014-07-18
      • 2017-07-15
      • 2019-02-24
      相关资源
      最近更新 更多