建议链几个CUDA操作在openCV?



我想:

  1. 上传数据到CUDA世界
  2. 做几个CUDA操作(gem,阈值,dft等)
  3. 将结果下载到CPU world

如何以最佳方式优化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();

恕我直言,你的做法是正确的。OpenCV开发人员在gemm内部使用cuBLAS,除非你正在搜索几微秒,否则不需要搜索如何直接调用内核。

我要补充一两件事,

  1. 我观察到对gpu代码的第一次调用比下一个更长(可能是由于初始化开销),我通常先执行一两个操作,让opencv正确初始化,然后对我的代码进行基准测试。

  2. 当使用流时,不要忘记在每次调用时使用它们(流在阈值操作中丢失),以确保操作的正确执行顺序。如果性能对这些操作也有影响,你也可以使用cv::Stream将数据复制到GPU。

  3. 如果你对性能有任何疑问,你可以使用insight系统来测试你的代码,并确保操作在同一流中执行,并且没有不必要的同步。(参见NSight system获取更多信息)

如果你真的性能爱好者和需要这些几微秒,也许你可以试着看一看NVidia性能原始或cublas直接看这可以提高性能,但我真的怀疑。

最新更新