繁体   English   中英

GPU 上的 OpenCV FAST 检测器

[英]OpenCV FAST detector on 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

我在 Visual Studio 的 Windows 上运行它。 使用Debug配置时,GPU 检测执行速度更快。

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

(我没有对这里提供的代码进行测量。我知道由于上下文初始化,对某些 OpenCV 函数的第一次调用可能需要更长的时间来执行。)

这很可能与我关于 FAST 检测器的问题有关 BHawk 对 CPU 上的 SIMD 优化给出了合理的解释。

所以,第二个问题是:

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

初始化冗长的答案:)

问题 1:

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

问题 2:

在确定图像处理在 GPU 还是 CPU 上的性能更好时,有几个因素在起作用。

1:内存管理

GPU 处理的主要瓶颈是将数据加载到 GPU 并从 GPU 检索数据。 在非常大的图像(在您的情况下为 16 兆像素)的情况下,这个瓶颈可能成为一个重大障碍。 当您将图像加载到 GPU 上,然后将图像留在那里以通过 OpenGL 上下文进行操作和显示时(就像您在 3D 游戏引擎中看到的那样),GPU 工作得最好。

2:串行与并行

GPU 由数千个并行运行的小型处理核心组成。 因此,他们能够同时执行许多小任务。 另一方面,CPU 经过优化以串行执行复杂的任务。 这意味着某些任务(大图像上下文、复杂计算、多步骤过程)在 CPU 上的性能可能比在 GPU 上更好。 另一方面,使用小图像上下文且不需要多个处理步骤的更简单的任务在 GPU 上执行得更快。 更复杂的是,CPU 可以线程化以并行运行,具体取决于可用计算内核的数量。 最重要的是,SIMD 优化的 CPU 可以进一步并行化它们的处理。 因此,具有 4 个内核和 8 个 SIMD ALU 的单个 CPU 可以同时处理 32 条数据。 这与 GPU 中存在的 1000 个内核仍然相去甚远,但 CPU 内核的处理速度通常要快得多,因此具有 8 个 SIMD 的 4 个内核可能在某些任务上执行得更快。 当然,如果您使用具有更多内核或更多 ALU 的系统,CPU 速度也会增加,如果减少数量,则速度会降低。

结论

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

我必须通读源代码才能确切了解此特定功能在 CPU 上运行速度的方式和原因,而不是 GPU,但我对此并不感到惊讶。 关于为什么一个实现与另一个实现不同数量的功能,这也需要通读,但它可能是为了内存分配或优化目的而不同地改变每个实现的功能。

抱歉回答太长,但这是一个复杂的讨论话题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM