-1

我正在尝试使用 OpenCV 和 CUDA 执行一些图像膨胀。filter->apply(...)我使用不同的filter对象和不同的调用两个调用,一个Mat接一个,每次都指定一个不同的流来使用。从附加的 nvvp 分析信息中可以看出,它们确实在不同的流中执行,但它们是按顺序运行的,而不是并行运行的。由于某种原因,这似乎是由 CPU 等待流 ( cudaStreamSynchronize) 引起的。 nvvp截图 为什么 OpenCV 能做到这一点?我没有明确地调用等待流或任何东西,还有什么问题?

这是实际的代码:

    cv::Mat hIm1, hIm2;
    cv::imread("/path/im1.png", cv::IMREAD_GRAYSCALE).convertTo(hIm1, CV_32FC1);
    cv::imread("/path/im2.png", cv::IMREAD_GRAYSCALE).convertTo(hIm2, CV_32FC1);
    cv::cuda::GpuMat dIm1(hIm1);
    cv::cuda::GpuMat dIm2(hIm2);

    cv::cuda::Stream stream1, stream2;

    const cv::Mat strel1 = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(41, 41));
    cv::Ptr<cv::cuda::Filter> filter1 = cv::cuda::createMorphologyFilter(cv::MORPH_DILATE, dIm1.type(), strel1);
    const cv::Mat strel2 = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(41, 41));
    cv::Ptr<cv::cuda::Filter> filter2 = cv::cuda::createMorphologyFilter(cv::MORPH_DILATE, dIm2.type(), strel2);
    cudaDeviceSynchronize();
    filter1->apply(dIm1, dIm1, stream1);
    filter2->apply(dIm2, dIm2, stream2);
    cudaDeviceSynchronize();

图像尺寸为 512×512;我尝试了较小的(低至 64×64),但无济于事!

4

1 回答 1

0

按顺序运行应用程序是用户的责任。

几个最佳实践:

  1. 流水线化您的代码,以便同时使用 CPU 和 GPU。将 GPU 调用设为异步。
  2. GPU 需要资源才能按顺序运行。如果 filter1() 使用了 100% 的 GPU,则 filter2() 将在管道中等待直到 filter1() 完成。

请查看分析器中的 GPU 利用率数据以获取更多详细信息。

于 2020-06-22T17:35:15.733 回答