2016-10-07 84 views
0

我运行下面这段代码快速检测仪:OpenCV的GPU上

cv::Ptr<cv::FastFeatureDetector> fastDetector = cv::FastFeatureDetector::create(100, true, 2); 
cv::Ptr<cv::cuda::FastFeatureDetector> gpuFastDetector = cv::cuda::FastFeatureDetector::create(100, true, 2); 

std::vector<cv::KeyPoint> keypoints; 
std::vector<cv::KeyPoint> gpuKeypoints; 

cv::Mat frame; 
cv::cuda::GpuMat gFrame; 

frame = cv::imread("image1.jpg"); // 4608 x 3456 
cv::cvtColor(frame, frame, CV_BGR2GRAY); 
gFrame.upload(frame); 

gpuFastDetector->detect(gFrame, gpuKeypoints); 
std::cout << "FAST GPU " << gpuKeypoints.size() << std::endl; 
fastDetector->detect(frame, keypoints); 
std::cout << "FAST " << keypoints.size() << std::endl; 

,输出是:

FAST GPU 2210 
FAST 3209 

问题1

为什么同样的算法应用于具有相同参数的相同图像会导致检测到不同数量的关键点?

问题2

我在Windows在Visual Studio中运行此。当使用调试配置时,GPU检测执行速度更快。

但是,当使用版本时,正常(CPU)快速检测器执行得更快。此外,无论使用何种配置类型,GPU上的探测器性能都保持不变。但是,与Debug配置相比,在Release下执行检测时,CPU的性能急剧增加。

(我不是在我这里介绍的代码运行的测量结果。我知道一些OpenCV函数的第一个电话需要更长的时间,因为上下文初始化的执行。)

这很可能与我旧question about the FAST detector。 BHawk对CPU的SIMD优化给出了一个合理的解释。

所以,第二个问题是:

是否有可能在SIMD优化的CPU可以比GPU更快地执行FAST特征检测?这似乎不太可能。

回答

2

初始化冗长的答案:)

问题1:

调试编译不使用由一个发行版中使用的代码优化。调试版本将执行诸如保留临时变量数据的操作,以便您可以读取调试器中的数据。这通常意味着通常临时存在于CPU寄存器中的数据将溢出并在调试版本中被复制到RAM中。在优化的发行版本中不再需要相同的数据时将被丢弃。如果您在编译设置中禁用代码优化,则此差异可能会消失;我不确定我以前从未尝试过没有优化的情况下进行编译。

问题2:

确定图像处理是否将执行在GPU或CPU更好时,有几个因素在起作用。

1:内存管理

与GPU处理的主要瓶颈是加载数据到GPU和从GPU中检索它。对于非常大的图像(在您的情况下为16万像素),此瓶颈可能成为一个重大障碍。将图像加载到GPU上时,图形处理效果最佳,然后通过OpenGL上下文将图像留在那里进行处理和显示(如您在3D游戏引擎中看到的那样)。

2:串行与并行

GPU被由数千的并行运行的小处理核。因此,他们能够同时执行很多小任务。另一方面,CPU经过优化,可以串行执行复杂的任务。这意味着某些任务(大图像上下文,复杂计算,多步处理)在CPU上可能会比在GPU上执行得更好。另一方面,使用小图像上下文并且不需要多个处理步骤的更简单的任务在GPU上执行得更快。更复杂的是,根据可用计算内核的数量,CPU可以并行运行。最重要的是,SIMD优化的CPU可以进一步并行处理。因此,具有4个内核和8个SIMD ALU的单个CPU可以同时处理32个数据。这与GPU中1000个内核的距离仍然相差甚远,但CPU内核通常处理速度更快,因此具有8个SIMD的4个内核在某些任务中可能执行得更快。当然,如果你进入一个拥有更多内核或更多ALU的系统,CPU速度也会随之扩大,如果你减少了这个数量,CPU速度也会降低。

结论

由于内存瓶颈的,也有不适合于GPU的一些图像处理任务。数据IO否定了大规模并行的速度增益。如果您有高度优化的并行SIMD CPU算法,由于算法的性质和/或数据IO进出GPU的性能,CPU版本的执行速度肯定可能高于GPU。您可能还会发现,在小图像上,GPU版本仍然稍快。

我将不得不通读源代码来详细了解如何以及为什么此特定函数在CPU上运行得比GPU速度更快,但我并不觉得它确实如此。关于为什么在一个实现与另一个实现之间获得不同数量的功能,这还需要通读,但它可能是为了内存分配或优化目的而改变每个实现的实现的功能。

对不起,很长的回答,但它是一个复杂的讨论话题。

+0

对我来说,看起来很明智的是,如果我给它一大块工作嚼碎,GPU将显示其优势。我认为如果数据很大,花在数据处理上的时间花在数据处理上的时间花费在数据处理上花费的时间比就会减少。 图像数据传输速度慢于处理速度似乎不合理。而且,据我所知,这是你暗示GPU给予更小的图像时会超越CPU。 – ancajic