¿Versiones de GPU de algoritmos OpenCV más lentas que las versiones de CPU en mi máquina?

Al intentar acelerar un algoritmo simple utilizando la GPU con OpenCV, noté que en mi máquina (Ubuntu 12.10, NVidia 9800GT, Cuda 4.2.9, g ++ 4.7.2) la versión de la GPU es en realidad más lenta que la versión de la CPU. He probado con el siguiente código.

#include <opencv2/opencv.hpp>
#include <opencv2/gpu/gpu.hpp>

#include <chrono>
#include <iostream>

int main()
{
    using namespace cv;
    using namespace std;

    Mat img1(512, 512, CV_32FC3, Scalar(0.1f, 0.2f, 0.3f));
    Mat img2(128, 128, CV_32FC3, Scalar(0.2f, 0.3f, 0.4f));
    Mat img3(128, 128, CV_32FC3, Scalar(0.3f, 0.4f, 0.5f));

    auto startCPU = chrono::high_resolution_clock::now();
    double resultCPU(0.0);
    cout << "CPU ... " << flush;
    for (int y(0); y < img2.rows; ++y)
    {
        for (int x(0); x < img2.cols; ++x)
        {
            Mat roi(img1(Rect(x, y, img2.cols, img2.rows)));
            Mat diff;
            absdiff(roi, img2, diff);
            Mat diffMult(diff.mul(img3));
            Scalar diffSum(sum(diff));
            double diffVal(diffSum[0] + diffSum[1] + diffSum[2]);
            resultCPU += diffVal;
        }
    }
    auto endCPU = chrono::high_resolution_clock::now();
    auto elapsedCPU = endCPU - startCPU;
    cout << "done. " << resultCPU << " - ticks: " << elapsedCPU.count() << endl;

    gpu::GpuMat img1GPU(img1);
    gpu::GpuMat img2GPU(img2);
    gpu::GpuMat img3GPU(img3);
    gpu::GpuMat diffGPU;
    gpu::GpuMat diffMultGPU;
    gpu::GpuMat sumBuf;

    double resultGPU(0.0);
    auto startGPU = chrono::high_resolution_clock::now();
    cout << "GPU ... " << flush;
    for (int y(0); y < img2GPU.rows; ++y)
    {
        for (int x(0); x < img2GPU.cols; ++x)
        {
            gpu::GpuMat roiGPU(img1GPU, Rect(x, y, img2GPU.cols, img2GPU.rows));
            gpu::absdiff(roiGPU, img2GPU, diffGPU);
            gpu::multiply(diffGPU, img3GPU, diffMultGPU);
            Scalar diffSum(gpu::sum(diffMultGPU, sumBuf));
            double diffVal(diffSum[0] + diffSum[1] + diffSum[2]);
            resultGPU += diffVal;
        }
    }
    auto endGPU = chrono::high_resolution_clock::now();
    auto elapsedGPU = endGPU - startGPU;
    cout << "done. " << resultGPU << " - ticks: " << elapsedGPU.count() << endl;
}

Mi resultado es el siguiente:

CPU ... done. 8.05306e+07 - ticks: 4028470
GPU ... done. 3.22122e+07 - ticks: 5459935

Si esto ayuda: Mi generador de perfiles (System Profiler 1.1.8) me dice que la mayor parte del tiempo se invierte encudaDeviceSynchronize.

¿Estoy haciendo algo malo con la forma en que uso las funciones de la GPU de OpenCV o mi GPU es lenta?

Respuestas a la pregunta(1)

Su respuesta a la pregunta