簡體   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