영상처리 프로젝트를 진행하기 시작하면서 단순 CPU만 사용하는 프로그래밍에 한계를 체감하기 시작했다.

기본적으로 1280x720 픽셀데이터를 다루는데만 한번 모든 픽셀을 훓는데만 921,600번의 연산이 필요하고 여기에 갖가지 영상처리 알고리즘이 들어가면 기하급수적인 연산이 걸린다. 각 연산은 단순 사칙연산인 경우가 많으나 연산이 너무 많으니 한번 프로그램을 돌리면 짧게는 몇분, 길게는 몇십분씩 연산이 돌아가니 점점 머리가 미쳐가기 시작했다.


이 많은 연산을 해결하기 위해 우리의 위대한 선조들은 이미 그래픽카드를 개발했고 이 그래픽카드의 GPU속 100코어가 넘는 코어들을 이용해 수많은 계산을 병렬처리로 연산하면서 심하게 오래걸리는 연산들을 단 몇초, 몇 밀리초 안에 해결하도록 솔루션을 내 놓았다.


최근 다양한 GPU Acceleration을 찾아보던 중 익숙한 C#으로 다룰 수 있는 OpenCL 라이브러리를 사용해 GPU Acceleration을 사용해보기로 했다.

먼저 라이브러리를 받아야 하므로 아래 링크에서 가입하거나 로그인해서 라이브러리를 받자.

https://www.codeproject.com/KB/dotnet/1116907/OpenCLLib.zip


비주얼 스튜디오에 DLL 파일을 참조할 수 있는 사람들은 패스하시고 못하시는 분은 아래글을 따라 참조한다.

1. '솔루션 탐색기'에서 '참조'를 오른쪽 클릭 후 '참조 추가'를 누른다.


2. 새로이 뜨는 '참조 관리자'창 우측 하단의 '찾아보기(B)'를 클릭 후 넣고자 하는 라이브러리.dll의 경로를 찾아 '추가'한다.(여기서는 OpenCLlib.dll과 Cloo.dll이다.)

'참조 관리자' 창 내에 추가된 라이브러리의 좌측 체크박스를 체크한다.

이후 '확인' 버튼을 클릭한다.


이렇게 추가한 후 코드 상단에

using OpenCL;

을 추가하여 사용한다.


코드 예제 (소수를 찾는 예제.)

using System; using System.Drawing; using Accord.Imaging.Filters; using Accord.DataSets; public class Program { public static void Main() { int[] Primes = Enumerable.Range(2, 1000000).ToArray(); //2부터 1,000,000까지의 배열 생성 EasyCL cl = new EasyCL(); // EasyCL 초기화         blur.Accelerator = AcceleratorDevice.GPU; // GPU Acceleration Device 설정

cl.LoadKernel(IsPrime); // IsPrime을 커널로 로드

cl.Invoke("GetIfPrime", 0, Primes.Length, Primes); // GetIfPrime을 인코딩하고 0에서 Prime 길이만큼 변수 셋팅 후 Prime 대입

}


static string IsPrime

{

    get

{

return @" //인코딩 될 부분 kernel void GetIfPrime(global int* message) // 소수점 찾는 메서드 { int index = get_global_id(0); int upperl=(int)sqrt((float)message[index]); for(int i=2;i<=upperl;i++) { if(message[index]%i==0) { //printf("" %d / %d\n"",index,i ); message[index]=0; return; } } //printf("" % d"",index); }";

}

} }






+ Recent posts