(개인 프로젝트) CUDA를 이용해서 멀티 스레드로 작동하는 Image Filter 프로그램
소개
- 인원 : 1인
- 담당 : 프로그램 구현 전체
- 개발 환경 : Visual Studio 2015, CUDA 9.0
- 문제
- Input
- Data : 비트맵 이미지의 R, G, B 값
- 화면 입력 : 불러올 이미지 파일 이름, 적용 필터
- Output
- 화면 출력 : 필터 적용에 걸린 시간, 저장된 파일 이름
- 파일 출력 : 필터가 적용된 이미지
- Input
- 소스코드 : CUDA를 이용해서 멀티 스레드로 작동하는 Image Filter 프로그램
내용
1. 전부 다 늘릴 때와 각각을 늘릴 때의 차이
두 필터는 RGB에 일정 비율을 곱했다는 공통점이 있습니다. 이 중에 밝기 필터는 단순하게 모든 픽셀의 RGB값을 일정 비율만큼 더하면 되지만, 저희가 만든 필터는 채도를 올리는 방식이라서 붉은 계열 색상이라면 더 붉게 만들고, 푸른 계열 색상이라면 더 푸르게 만들어야 합니다.
2. 적용 방법
RGB 값을 비교하고, 가장 많이 쓰인 색을 높이는 방식으로 필터를 구현했습니다.
3. 병렬화 부분
그리드와 블록은 단순하게 설계하였습니다, 먼저 총 픽셀 수를 구하고, 블록 당 스레드 수를 지정하게 됩니다. 그리고 각 스레드는 한 픽셀 씩 맡아서 RGB값을 처리하게 됩니다. 이렇게 스레드가 한 픽셀을 맡게 되면 동기화 문제는 해결됩니다.
5. 결과 분석 (Intel i7-7700 & GTX 1070 기준)
각 필터 마다 CPU 시간을 GPU 시간으로 나누어서 계산한 차트입니다.
평균적으로 10배 이상의 성능 향상을 보이고, 그레이 필터는 다른 필터보다 더 빠른 23배 정도의 성능향상이 있었습니다.
아무래도 CPU나 GPU 둘 다 높은 성능 이라서 큰 차이가 보이지 않는 것 같습니다.
어려웠던 점
무작정 큰 값만 늘리다보니 문제가 발생했습니다. 이 주변은 하늘이라서 주로 파란색 값이 크지만, 이 부분은 구름과 겹쳐서 파란색보다 녹색이 더 많았습니다. 그래서 이 픽셀만 녹색이 더 증가하는 문제가 생기게 된다는 사실을 알았습니다.
이 문제를 해결하기 위해 허용 범위를 지정하였습니다. RGB 값의 차이가 일정 범위 이내라면 비슷한 값들을 한 번에 증가시켰습니다. 이렇게 증가시켰더니 이전 사진에서 구름 일부가 녹색으로 바뀌던 문제를 해결할 수 있었습니다.
배운 점
이전에 OpenMP만 사용할 때에는 CPU만 사용했기 때문에 스레드가 많아야 겨우 8개 정도였지만, 이번에는 그래픽 카드를 이용했기 때문에 훨씬 많은 수의 스레드를 생성하고 제어하였습니다. 이 프로젝트에서는 사진 파일이 가진 픽셀 수 만큼 스레드를 생성하였는데, 1024 X 1024의 사이즈를 가진 사진이라면 100만개 이상의 스레드를 생성하게 됩니다. 너무 많은 수의 스레드를 생성하다보니 이를 제어하는 것이 처음에는 어려웠지만, 점점 익숙해져서 잘 다룰 수 있게 되었습니다.