2016-10-07 125 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