OpenCL運行測試
由于雙目的分辨率會非常大计雌,因此特來測試下OpenCL的運算性能(奈何手中無英偉達)
環(huán)境:MacOS x86_64 Darwin 17.7.0
CPU:Intel Core i5-5350U
GPU:Intel HD Graphics 6000
OpenCV:OpenCV 4.2
編譯器:clang++
以下是選用一張4480x6720和一張640x480圖像做測試的結果郎汪,原始數(shù)據(jù)輸出:
測試結果(僅供參考)
像素:4480x6720,循環(huán)次數(shù):100次
Size:4480x6720
OpenCL time consume = 85.6954ms
Size:4480x6720
CPU time consume = 120.533ms
Size:4480 x 6720
OpenCL loops time consume = 1050.15 ms
Size:4480x6720
CPU loop time consume = 1058.4ms
-------------Process Complete------------像素:4480x6720移袍,循環(huán)次數(shù):100次
Size:4480x6720
OpenCL time consume = 86.6929 ms
Size:4480x6720
CPU time consume = 118.128 ms
Size:4480 x 6720
OpenCL loops time consume = 1055.27 ms
Size:4480x6720
CPU loops time consume = 1065.48 ms
-------------Process Complete------------像素4480x6720,循環(huán)次數(shù):1000
Size:4480x6720
OpenCL time consume = 86.6043 ms
Size:4480x6720
CPU time consume = 119.366 ms
Size:4480 x 6720
OpenCL loops time consume = 97815.7 ms
Size:4480x6720
CPU loops time consume = 105973 ms
-------------Process Complete------------像素:640x480钳榨,循環(huán)次數(shù):100次
Size:640x480
OpenCL time consume = 3.01333 ms
Size:640x480
CPU time consume = 1.55183 ms
Size:640 x 480
OpenCL loops time consume = 109.044 ms
Size:640x480
CPU loops time consume = 84.6049 ms
-------------Process Complete------------像素:640x480,循環(huán)次數(shù):100次
Size:640x480
OpenCL time consume = 3.2602 ms
Size:640x480
CPU time consume = 1.29072 ms
Size:640 x 480
OpenCL loops time consume = 107.968 ms
Size:640x480
CPU loops time consume = 86.4707 ms
-------------Process Complete------------像素:640x480州藕,1000次
Size:640x480
OpenCL time consume = 3.23095 ms
Size:640x480
CPU time consume = 1.17594 ms
Size:640 x 480
OpenCL loops time consume = 1164.68 ms
Size:640x480
CPU loops time consume = 940.939 ms
-------------Process Complete------------像素:640x480,10000次
Size:640x480
OpenCL time consume = 3.64011 ms
Size:640x480
CPU time consume = 1.2437 ms
Size:640 x 480
OpenCL loops time consume = 10745.1 ms
Size:640x480
CPU loops time consume = 8566.75 ms
-------------Process Complete------------
表格總結
表1:
分辨率 | CPU處理1次 | OpenCL處理1次 | CPU循環(huán)100次 | OpenCL循環(huán)100次 |
---|---|---|---|---|
640x480 | 1.55 ms | 3.01 ms | 84.60 ms | 109.04 ms |
640x480 | 1.29 ms | 3.26 ms | 86.47 ms | 107.96 ms |
4480x6720 | 120.53 ms | 85.69 ms | 1058.4 ms | 1050.15 ms |
4480x6720 | 118.12 ms | 86.69 ms | 1065.48 ms | 1055.27 ms |
表2:
分辨率 | 循環(huán)次數(shù) | CPU處理1次 | OpenCL處理1次 | CPU循環(huán) | OpenCL循環(huán) |
---|---|---|---|---|---|
640x480 | 100次 | 1.55 ms | 3.01 ms | 84.60 ms | 109.04 ms |
640x480 | 100次 | 1.29 ms | 3.26 ms | 86.47 ms | 107.96 ms |
640x480 | 1000次 | 1.17 ms | 3.23 ms | 940.93 ms | 1164.68 ms |
640x480 | 10000次 | 1.24 ms | 3.64 ms | 8566.75 ms | 10745.10 ms |
4480x6720 | 100次 | 120.53 ms | 85.69 ms | 1058.4 ms | 1050.15 ms |
4480x6720 | 100次 | 118.12 ms | 86.69 ms | 1065.48 ms | 1055.27 ms |
4480x6720 | 1000次 | 119.36 ms | 86.60 ms | 1059.73 s | 978.15 s |
圖表分析
為此我專門做了如下圖表:
因為這個數(shù)據(jù)差距有些大酝陈,不好直觀看出差距床玻,那么我們不妨采用log10
為底的坐標刻度:
初步分析
- 在分辨率較小的情況下,使用CPU處理會快于GPU(OpenCL),分辨率較大則GPU占優(yōu)如圖表中顯示沉帮。
- 在分辨率大(>1080P)而且循環(huán)次數(shù)多(>1000)的情況下锈死,使用GPU(OpenCL)明顯會快出CPU,參見表2最后一組數(shù)據(jù),1000次循環(huán)整整快出了81.58s穆壕。
當然待牵,由于平臺不同,這個結論不一定具有普適性
結尾放上測試代碼喇勋,簡單的canny
邊緣檢測
edge_test.cpp
#include <opencv2/opencv.hpp>
using namespace cv;
void opencl_process(std::string &filename); //處理一張圖(OpenCL)
void cpu_process(std::string &filename); //處理一張圖(CPU)
void loops_opencl(std::string &filename,int ×); //循環(huán)處理(OpenCL)
void loops_cpu(std::string &filename,int ×); //循環(huán)處理(CPU)
int main(int argc, char** argv)
{
std::string filename = 文件名;
int times = 循環(huán)次數(shù);
opencl_process(filename);
cpu_process(filename);
loops_opencl(filename,times);
loops_cpu(filename,times);
std::cout <<"-------------Process Complete------------"<<std::endl;
return 0;
}
void opencl_process(std::string &filename){
double start = (double)getTickCount();
UMat img, gray;
// 復制缨该,從Mat->UMat
imread(filename, IMREAD_COLOR).copyTo(img);
cvtColor(img, gray, COLOR_BGR2GRAY);
GaussianBlur(gray, gray,Size(7, 7), 1.5);
Canny(gray, gray, 0, 50);
double time_consume = ((double)getTickCount() - start) / getTickFrequency();
std::cout << "Size:" << gray.cols << "x" << gray.rows << std::endl;
std::cout << "OpenCL time consume = " << time_consume * 100<< " ms" << std::endl;
}
void cpu_process(std::string &filename){
double start = (double)getTickCount();
Mat img, gray;
imread(filename, IMREAD_COLOR).copyTo(img);
cvtColor(img, gray, COLOR_BGR2GRAY);
GaussianBlur(gray, gray,Size(7, 7), 1.5);
Canny(gray, gray, 0, 50);
double time_consume = ((double)getTickCount() - start) / getTickFrequency();
std::cout << "Size:" << gray.cols << "x" << gray.rows << std::endl;
std::cout << "CPU time consume = " << time_consume * 100<< " ms" << std::endl;
}
void loops_opencl(std::string &filename,int ×){
double start = (double)getTickCount();
UMat img, gray;
for(int i=0;i<=times;i++){
imread(filename, IMREAD_COLOR).copyTo(img);
cvtColor(img, gray, COLOR_BGR2GRAY);
GaussianBlur(gray, gray,Size(7, 7), 1.5);
Canny(gray, gray, 0, 50);
}
double time_consume = ((double)getTickCount() - start) / getTickFrequency();
std::cout << "Size:" << gray.cols << " x " << gray.rows << std::endl;
std::cout << "OpenCL loops time consume = " << time_consume * 100<< " ms" << std::endl;
}
void loops_cpu(std::string &filename,int ×){
double start = (double)getTickCount();
Mat img, gray;
for (int i =0; i < times; i++){
imread(filename, IMREAD_COLOR).copyTo(img);
cvtColor(img, gray, COLOR_BGR2GRAY);
GaussianBlur(gray, gray,Size(7, 7), 1.5);
Canny(gray, gray, 0, 50);
}
double time_consume = ((double)getTickCount() - start) / getTickFrequency();
std::cout << "Size:" << gray.cols << "x" << gray.rows << std::endl;
std::cout << "CPU loops time consume = " << time_consume * 100<< " ms" << std::endl;
}
更改文件名和循環(huán)次數(shù)即可。
編譯命令參考:
clang++ -std=c++11 edge_test.cpp -o edge_test `pkg-config --cflags --libs opencv4`
注意:opencv 4茄蚯,開啟c++11編譯選項压彭。