개발자가 뭔가를 설계 할때 어려움을 격는 부분이 항상 있는 부분이 있다고 한다면, 아마 for() 로 돌리는 구문을 어떻게 빠르게 할 것인가? 또는 이걸 thread 로 어떻게 만들 수 있을까? 일 겁니다.
MinGW-W64 의 경우는 이 작업을 -fopenmp 명령과 함께 compile & link 하면 #pragma omp 를 사용할 수 있습니다. 다만, 3.0 까지는 지원이 안되기 때문에 좀 더 자세한 thread 분리는 어려운 부분이 있습니다. openmp 사용시엔 pthread 가 사용 되는건 추가로 인지 하고 있어야 합니다.
먼저 코드상에 직접 사용된 예를 보면 ...
위 영역 처럼 #pragma omp parallel for 만 지시해서 다음에 오는 for() 문 자체를 pthread 로 분리 하게 됩니다. 매우 간단 하면서도 openmp 가 없는 상태에서 코드를 빌드 해도 문제가 되지 않는 방법으로 매우 좋습니다.
또한 여러 복합 for() 문이 쓰인 경우는 ... for() 문 안에 바로 지정 하던 인자를 밖으로 뺀 다음, 여러개의 for 문이 사용하는 대상을 private()으로 지정하여 threading 하도록 하였습니다.
또한 기존에 std::vector<T> 를 쓰던 부분은 openmp 시 문제를 야기 하므로 변경 한 부분도 있습니다. 아래는 librawprocessor 의 ApplyMedianFilter() 함수의 일부로서, 다음과 같이 변경 되었습니다.
medimatrix 는 원래 std::vector< unsigned short > medimatrix 로, push_back 으로 unsigned short vector 에 채워 진 다음, algorithm 의 sort() 를 통해 정렬 후, vector 의 길이 반에 해당하는 중간 값을 찾는 알고리즘 이었으나, 속도와 openmp 호환성을 위해 많은 부분을 변경한 경우 입니다. 그 성능 차이는 거의 10초 걸리던 것을 1초 정도로 줄이는 기염을 보인 정도로, 꽤 많은 성능 향상을 가져 온 부분 이었습니다.
이런식으로 성능 향상을 위해 약간의 변경이 큰 결과를 가져온 것은 아래 이미지 처럼 확인이 가능 합니다.
하나의 쓰레드로 구동한 속도.
openmp 로 구동한 속도.
속도 비교에 사용된 것은 최신 버젼의 raw_resize 로서, 64bit 버젼으로 openmp 를 쓴 것과 안 쓴 것으로 분류 해서 구동 해 보았습니다. 사용된 영상은 가로 세로 3072 의 크기를 가지는 의료영상으로서, 다음 차례로 filter 를 적용하여 측정 된 속도를 확인 하였습니다.
- 영상 크기 BiCubic 필터로 200% (실제 면적은 4배가 됨) 크기 키움.
- 밝기, 감마, 명암비 조정 + 샤픈 과 미이언 필터 적용.
전체적으로 걸린 시간을 보면 단순 CPU 명령어만 최적화 해서 하나의 쓰레드(프로세스) 로 만 처리 할 경우 전체 10초 정도의 속도에서, openmp 로 최소한의 최적화를 한 경우 약 3초로, 거의 3배 이상의 속도향상을 얻을 수 있었습니다.
각 요소들의 성능 향상을 대충 감안 해 보면...
- 크기 변경 : 724ms -> 437ms ( 40% 향상 )
- 밝기 조정 : 15ms -> 12ms ( 20% 향상 )
- 감마 조정 : 22ms -> 13ms ( 40% 향상 )
- 대비 조정 : 17ms -> 13ms ( 25% 향상 )
- sharpen : 3848ms -> 1101ms ( 70% 향상 )
- median : 10036ms -> 3014ms ( 70% 향상 )
전반적으로 많은 load 가 걸리는 부분들이 향상이 된 것을 확인이 가능 하였으며, 적절한 openmp 사용이 큰 성능 향상에 이바지 한다는 것을 도출 할 수 있었습니다.
openmp 가 적용된 소스는 아래 URL 에서 누구나 확인하고 다운로드 및 clone 하여 사용할 수 있습니다. (MIT License 임)
- https://github.com/rageworx/librawprocessor
test 에 사용된 프로그램은 아래에서 다운로드 받을 수 있습니다.
구동을 하기 위해서는 64bit Windows 와, AVX 명령어를 지원하는 Intel 또는 AMD CPU가 필요 합니다. 또한 테스트에 사용된 영상은 제공이 불가능 합니다.