반응형



OpenCL 사용 여부에 따라 OpenCV 성능이 어떻게 달라지는지 테스트해보았습니다.



테스트는 다음과 같이 진행했습니다.


OpenCL을 활성화 한 상태에서 소벨을 10000번 진행하고


ocl::setUseOpenCL(true);


for (int i = 0; i < 10000; i++) {
UMat dst;
Sobel(src, dst, -1, 1, 0);
}



OpenCL을 비활성화한 상태에서 소벨을 10000번 진행합니다.


ocl::setUseOpenCL(false);


for (int i = 0; i < 10000; i++) {
UMat dst;
Sobel(src, dst, -1, 1, 0);
}




테스트 결과 OpenCL을 활성화 했을 때가 비활성화 했을때보다 10배 정도 빨라졌습니다.

(테스트 환경에 따라 달라질 수 있습니다.)


1 GPU device (s) detected
- Device 0 ---
Name : Intel(R) HD Graphics 620
Availability : 1
Image Support : 1
OpenCL C version : OpenCL C 2.0
Sobel Test : OpenCL Enabled  --- Done. Processing Time : 25.757 sec.
Sobel Test : OpenCL Disabled  --- Done. Processing Time : 316.561 sec.




테스트에 사용한 전체 코드입니다.


#include "opencv2/opencv.hpp"
#include "opencv2/core/ocl.hpp"
#include <iostream>

using namespace std;
using namespace cv;


int  main()
{

// OpenCL을 사용할 수 있는지 테스트
if (!ocl::haveOpenCL()) {
cout << "에러 : OpenCL을 사용할 수 없는 시스템입니다." << endl;
return  -1;
}

// 컨텍스트 생성
ocl::Context context;
if (!context.create(ocl::Device::TYPE_GPU)) {
cout << " 에러 : 컨텍스트를 생성할 수 없습니다." << endl;
return  -1;
}

// GPU 장치 정보
cout << context.ndevices() << " GPU device (s) detected " << endl;
for (size_t i = 0; i < context.ndevices(); i++) {
ocl::Device device = context.device(i);
cout << " - Device " << i << " --- " << endl;
cout << " Name : " << device.name() << endl;
cout << " Availability : " << device.available() << endl;
cout << "Image Support : " << device.imageSupport() << endl;
cout << " OpenCL C version : " << device.OpenCL_C_Version() << endl;
}

// 장치 0 번 사용
ocl::Device(context.device(0));

// 입력 이미지
Mat mSrc = imread("lena.jpg" , IMREAD_GRAYSCALE ) ;
UMat src = mSrc.getUMat(ACCESS_READ);

// 실행 시간 측정
static int64 start, end;
static float time;


// OpenCL Enable 상태에서 Sobel을 10000번 반복
ocl::setUseOpenCL(true);
cout << " Sobel Test : OpenCL Enabled ";

start = getTickCount();
for (int i = 0; i < 10000; i++) {
UMat dst;
Sobel(src, dst, -1, 1, 0);
}
end = getTickCount();
time = (end - start) / getTickFrequency();
cout << " --- Done. Processing Time : " << time << " sec. " << endl;


// OpenCL Disable 상태에서 Sobel을 10000번 반복
ocl::setUseOpenCL(false);
cout << " Sobel Test : OpenCL Disabled ";

start = getTickCount();
for (int i = 0; i < 10000; i++) {
UMat dst;
Sobel(src, dst, -1, 1, 0);
}
end = getTickCount();
time = (end - start) / getTickFrequency();
cout << " --- Done. Processing Time : " << time << " sec. " << endl;

return  0;
}




참고


https://sites.google.com/site/uranishi/opencv_imageprocessing/opencl_opencv

https://docs.opencv.org/3.3.0/dc/d71/tutorial_py_optimization.html




최초 작성 2019. 1. 22



반응형

포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
댓글로 알려주시면 빠른 시일내에 답변을 드리겠습니다.

여러분의 응원으로 좋은 컨텐츠가 만들어집니다.
지금 본 내용이 도움이 되었다면 유튜브 구독 부탁드립니다. 감사합니다 : )

유튜브 구독하기


제가 쓴 책도 한번 검토해보세요.

  1. Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.01.22 17:11 신고

    OpenCV 바이너리 배포판도 OpenCL을 사용할 수 있습니다.

  2. ryu 2019.01.23 10:35

    음 다른 함수도 opencl UMat 테스트 해보니
    {
    cvtColor(src, dst, COLOR_BGR2GRAY);
    GaussianBlur(dst, dst, Size(7, 7), 1.5);
    Canny(dst, dst, 0, 50);
    }
    대충 15~20%정도만 속도 향상이 있내요 (i5 & gtx1060)
    그리고 findContour 함수는 아예 UMat쪽이 두배나 느리더군요.

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.01.23 12:18 신고

      Canny 함수만 사용하여 테스트해봤는데 포스팅 결과와 비슷하게 나왔습니다.

      구현한 소스 코드 차이 또는 컴퓨터에 있는 GPU 사양에 따라 달라질 수 있나봅니다.

  3. shsh 2019.03.02 22:10

    UMat src = mSrc.getUMat(ACCESS_READ);
    이 부분에서 OpenCL 디바이스 영역 즉, CPU 메모리에서 GPU 메모리로 복사를 해야하는데 이부분이 시간이 굉장히 오래 걸리더라고요
    혹시 최적화하는 방법에 어떤게 있을까요??

+ Recent posts