Pourquoi Opencv code GPU est plus lent que le CPU?

Je suis en utilisant opencv242 + VS2010 par un ordinateur portable.

J'ai essayé de faire un simple test du GPU bloc dans OpenCV, mais elle a montré que le GPU est 100 fois plus lent que le CPU codes.
Dans ce code, j'ai juste à tourner la couleur de l'image à niveaux de gris de l'image, utilisez la fonction de cvtColor

Voici mon code, PART1 est code de CPU(test cpu RGB2GRAY), PART2 est de télécharger l'image sur GPU, PART3 de la GPU RGB2GRAY, PART4 du CPU est RGB2GRAY de nouveau.
Il y a 3 choses qui me rend si vous vous demandez:

1 Dans mon code, part1 est de 0,3 ms, tandis que part4 (qui est exactement la même chose avec part1) est de 40ms!!!

2 La partie2 téléchargement de l'image sur GPU est 6000ms!!!

3 Part3( GPU codes) est de 11 ms, c'est si lent pour cette simple image!

    #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;
}
  • Ce n'est pas que le GPU est généralement "lent". Toutefois, la mémoire de transfert entre l'hôte et le périphérique est extrêmement lent. GPU calcul n'a de sens que si vous pouvez vous décharger d'une très grande, très calcul parallèle à l'appareil.
  • Devriez également vérifier answers.opencv.org/question/1670/...
  • Ensuite, vous passez pas alloué GpuMat vous avez de la mémoire graphique de répartition à l'intérieur de GPU-optimisé fonctions. Pour éviter cela, vous devez préallouer votre mémoire avec la bonne taille avant de l'utilisation de fonction.
InformationsquelleAutor David Ding | 2012-08-22