OpenCV GPU模糊很慢

anc*_*jic 2 opencv cuda gpu

GPU: GeForce GTX 750

中央处理器: Intel i5-4440 3.10 GHz

这是一个我正在运行的简单C++代码.

    #include <iostream>
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2\gpu\gpu.hpp"

    int main(int argc, char** argv) {
        cv::Mat img0 = cv::imread("IMG_0984.jpg", CV_LOAD_IMAGE_GRAYSCALE); // Size 3264 x 2448
        cv::Mat img0Blurred;

        cv::gpu::GpuMat gpuImg0(img0);
        cv::gpu::GpuMat gpuImage0Blurred;

        int64 tickCount;

        for (int i = 0; i < 5; i++)
        {
            tickCount = cv::getTickCount();
            cv::blur(img0, img0Blurred, cv::Size(7, 7));
            std::cout << "CPU Blur " << (cv::getTickCount() - tickCount) / cv::getTickFrequency() << std::endl;

            tickCount = cv::getTickCount();
            cv::gpu::blur(gpuImg0, gpuImage0Blurred, cv::Size(7, 7));
            std::cout << "GPU Blur " << (cv::getTickCount() - tickCount) / cv::getTickFrequency() << std::endl;

        }

        cv::gpu::DeviceInfo deviceInfo;
        std::cout << "Device Info: "<< deviceInfo.name() << std::endl;

        std::cin.get();

        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

结果,我通常得到这样的东西:

CPU Blur: 0.01
GPU Blur: 1.7
CPU Blur: 0.009
GPU Blur: 0.012
CPU Blur: 0.009
GPU Blur: 0.013
CPU Blur: 0.01
GPU Blur: 0.012
CPU Blur: 0.009
GPU Blur: 0.013

Device Info: GeForce GTX 750
Run Code Online (Sandbox Code Playgroud)

因此GPU上的第一个操作需要时间.

但是,其余的GPU调用呢?

为什么GPU不为此提供任何加速.毕竟这是一个很大的形象(3264 x 2448).并行化的任务很好,不是吗?

我的CPU是好的还是我的GPU那么糟糕?或者这是组件之间的某种通信问题?

X3l*_*liF 6

你的第一个gpu测量结果远远不是其他人,我经历过同样的事情.第一次调用opencv内核(erode/dilate/etc ...)比其他内容更长.在应用程序中,当我们初始化GPU内存时,我们首先调用了cv :: gpu :: XX,以便不会产生这种测量噪音.

我也看到cv :: gpu在每次调用后都使用cudaDeviceSynchronize而没有cv :: gpu :: Stream参数.这可能很长,会导致测量噪声.然后opencv可能会为临时缓冲区分配内存,以存储用于模糊图像的内核.

我没有在你的例子中看到gpuImage0Blurred的分配,你能确定你的目标图像是在循环外正确分配的,否则你也会测量这个矩阵的分配时间.

使用nvvp可以为您提供运行应用程序以删除不必要操作时实际发生的情况的线索.

编辑:

#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2\gpu\gpu.hpp"


int main(int argc, char** argv) {
    cv::Mat img0 = cv::imread("IMG_0984.jpg", CV_LOAD_IMAGE_GRAYSCALE); // Size 3264 x 2448
    cv::Mat img0Blurred;


    cv::gpu::GpuMat gpuImg0;
    cv::gpu::Stream stream;
    stream.enqueueUpload(img0, gpuImg0);
    stream.waitForCompletion();

    // allocates the matrix outside the loop
    cv::gpu::GpuMat gpuImage0Blurred( gpuImg0.size(), gpuImg0.type() );

    int64 tickCount;

    for (int i = 0; i < 5; i++)
    {
        tickCount = cv::getTickCount();
        cv::blur(img0, img0Blurred, cv::Size(7, 7));
        std::cout << "CPU Blur " << (cv::getTickCount() - tickCount) / cv::getTickFrequency() << std::endl;

        tickCount = cv::getTickCount();
        cv::gpu::blur(gpuImg0, gpuImage0Blurred, cv::Size(7, 7), cv::Point(-1, -1), stream);
        // ensure operations are finished  before measuring time spent doing operations
        stream.WaitCompletion();
        std::cout << "GPU Blur " << (cv::getTickCount() - tickCount) / cv::getTickFrequency() << std::endl;

    }

    std::cin.get();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

是的,事实证明waitForCompletion这一切都有所不同.我得到了与开头相同的值:

CPU Blur: 0.01
GPU Blur: 1.7
CPU Blur: 0.009
GPU Blur: 0.012
CPU Blur: 0.009
GPU Blur: 0.013
CPU Blur: 0.01
GPU Blur: 0.012
CPU Blur: 0.009
GPU Blur: 0.013
Run Code Online (Sandbox Code Playgroud)