Warum Opencv GPU-code langsamer ist als die CPU?

Ich bin mit opencv242 + VS2010 von einem notebook.

Ich habe versucht zu tun, einige einfache test der GPU-block in OpenCV, aber es zeigte die GPU ist 100-mal langsamer als die CPU-codes.
In diesem code, ich habe gerade drehen Sie das Farbbild in ein Graustufenbild, verwenden Sie die Funktion cvtColor

Hier ist mein code, PART1 ist ein CPU-code(test-cpu RGB2GRAY), PART2 ist Bild hochladen GPU, PART3 ist GPU RGB2GRAY, PART4 die CPU RGB2GRAY wieder.
Es gibt 3 Dinge, die macht mich so Fragen:

1 In meinem code, part1 ist 0.3 ms, während Teil4 (das ist genau das selbe mit part1) ist 40ms!!!

2 Den part2 das Bild hochladen zu GPU ist 6000ms!!!

3 Part3( GPU-codes) ist 11ms, es ist so langsam für dieses einfache Bild!

    #include "StdAfx.h"
    #include <iostream>
    #include "opencv2/opencv.hpp"
    #include "opencv2/gpu/gpu.hpp"
    #include "opencv2/gpu/gpumat.hpp"
    #include "opencv2/core/core.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include <cuda.h>
    #include <cuda_runtime_api.h>
    #include <ctime>
    #include <windows.h>

    using namespace std;
    using namespace cv;
    using namespace cv::gpu;

    int main()
    {
        LARGE_INTEGER freq;
        LONGLONG QPart1,QPart6;
        double dfMinus, dfFreq, dfTim;
        QueryPerformanceFrequency(&freq);
        dfFreq = (double)freq.QuadPart;

        cout<<getCudaEnabledDeviceCount()<<endl;
        Mat img_src = imread("d:\\CUDA\\train.png", 1);

        //PART1 CPU code~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        //From color image to grayscale image.
        QueryPerformanceCounter(&freq);
        QPart1 = freq.QuadPart;
        Mat img_gray;
        cvtColor(img_src,img_gray,CV_BGR2GRAY);
        QueryPerformanceCounter(&freq);
        QPart6 = freq.QuadPart;
        dfMinus = (double)(QPart6 - QPart1);
        dfTim = 1000 * dfMinus / dfFreq;
        printf("CPU RGB2GRAY running time is %.2f ms\n\n",dfTim);

        //PART2 GPU upload image~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        GpuMat gimg_src;
        QueryPerformanceCounter(&freq);
        QPart1 = freq.QuadPart;
        gimg_src.upload(img_src);
        QueryPerformanceCounter(&freq);
        QPart6 = freq.QuadPart;
        dfMinus = (double)(QPart6 - QPart1);
        dfTim = 1000 * dfMinus / dfFreq;
        printf("Read image running time is %.2f ms\n\n",dfTim);

        GpuMat dst1;
        QueryPerformanceCounter(&freq);
        QPart1 = freq.QuadPart;

        /*dst.upload(src_host);*/
        dst1.upload(imread("d:\\CUDA\\train.png", 1));

        QueryPerformanceCounter(&freq);
        QPart6 = freq.QuadPart;
        dfMinus = (double)(QPart6 - QPart1);
        dfTim = 1000 * dfMinus / dfFreq;
        printf("Read image running time 2 is %.2f ms\n\n",dfTim);

        //PART3~ GPU code~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        //gpuimage From color image to grayscale image.
        QueryPerformanceCounter(&freq);
        QPart1 = freq.QuadPart;

        GpuMat gimg_gray;
        gpu::cvtColor(gimg_src,gimg_gray,CV_BGR2GRAY);

        QueryPerformanceCounter(&freq);
        QPart6 = freq.QuadPart;
        dfMinus = (double)(QPart6 - QPart1);
        dfTim = 1000 * dfMinus / dfFreq;
        printf("GPU RGB2GRAY running time is %.2f ms\n\n",dfTim);

        //PART4~CPU code(again)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        //gpuimage From color image to grayscale image.
        QueryPerformanceCounter(&freq);
        QPart1 = freq.QuadPart;
        Mat img_gray2;
        cvtColor(img_src,img_gray2,CV_BGR2GRAY);
        BOOL i_test=QueryPerformanceCounter(&freq);
        printf("%d \n",i_test);
        QPart6 = freq.QuadPart;
        dfMinus = (double)(QPart6 - QPart1);
        dfTim = 1000 * dfMinus / dfFreq;
        printf("CPU RGB2GRAY running time is %.2f ms\n\n",dfTim);

        cvWaitKey();
        getchar();
        return 0;
    }
  • Es ist nicht so, dass die GPU ist in der Regel "slow". Allerdings, Speicher-transfer zwischen host und device ist extrem langsam. GPU-Berechnung macht nur Sinn, wenn Sie verschieben kann, eine sehr große, hoch parallele Berechnung auf dem Gerät.
  • Sollten auch überprüfen, answers.opencv.org/question/1670/...
  • Dann übergeben Sie die nicht zugeordnet GpuMat Sie haben GPU-Speicher Zuweisung im inneren GPU-optimierten Funktionen. Um es zu vermeiden, sollten Sie preallocate Ihr Gedächtnis mit der richtigen Größe vor der Funktion usage.
InformationsquelleAutor David Ding | 2012-08-22
Schreibe einen Kommentar