영상처리 개발업무를 하며 속도 최적화에 대한 고민을 많이 한다.
전역 변수 할당, 행단위 접근, 포인터 접근, 참조 전달, PipeLine Architecture, SIMD기법, Parallel Processing (OpenCL, CUDA, TBB)등.
기본 언어 최적화를 진행 하지만, 대규모 데이터에서 빠른 처리를 보이는 방법은 역시 Parallel Processing이다.
하지만, 모든 방법에는 그에 따른 비용이 발생하고 (ex. Context Switching, Overhead), 성능 목표와 목적간의 비용을 조절하는 과정이 필요하다.
SIMD와 CUDA 같은 병렬 기법은 상대적으로 개발기간이 길어지고, 적용할 수 있는 알고리즘이 제한적이다.
다시 최적화에 대한 이야기로 돌아와서, “if문은 성능을 저하시킨다” 라는 말을 들어왔다.
저 말의 진위는 분기문이 많아지면, 분기 예측을 더 많이하고, 조건에 따라 실패 확률이 증가 한다.
실패 시, 대기 명령을 flush시키고 fetch단계부터 다시 작성할 때 성능 손실이 생긴다.
신호처리를 위한 npp 라이브러리. 기존 npp 영상처리 라이브러리와 유사한 함수가 다수 존재한다. 자주 사용하지 않아 나열만 해놓는다.
피치 이미지 저장 할당 및 해제를 위한 루틴.
이러한 방법들은 편의를 위해 제공된다. 각 픽셀 행 끝에 추가 패딩 바이트를 포함할 수 있는 메모리를 할당한다. NPP이미지 처리 원시 요소들이 제대로 작동하려면 패딩이 필수는 아니지만, 패딩이 없으면 제대로 패딩된 이미지에 비해 성능 저하가 심각할 수 있다.
두 이미지의 픽셀 또는 한 이미지와 일정한 값의 픽셀을 비교하여 이진 결과 이미지를 만듭니다. 다중 채널 이미지 유형의 경우, 모든 채널에 대해 조건이 충족되어야 하며, 그렇지 않으면 비교가 거진으로 간주 됩니다. “이진”결과 이미지는 타입 8u_C1입니다. 거진은 0으로 참은 NPP_MAX_8U로 표현됩니다.
픽셀별 임계값 및 비교 연산을 위한 방법들.
근래에 필자의 솔루션은 WPF + Cpp DLL 형식으로 작업을 한다. 이러는 와중 프로그램 실행 전 DLL과 프로그램의 버전을 관리하기 위한 방법을 고민하여 정리한다.
이미지의 통계적 속성을 계산하기 위한 기본형식. 일부 통계 기본 요소는 계산 중에 스크래치 버퍼도 필요하다. (https://docs.nvidia.com/cuda/npp/introduction.html#general_conventions_lb_1general_scratch_buffer)
이미지의 통계적 속성을 계산하기 위한 기본형식. 일부 통계 기본 요소는 계산 중에 스크래치 버퍼도 필요하다. (https://docs.nvidia.com/cuda/npp/introduction.html#general_conventions_lb_1general_scratch_buffer)
형태학적 이미지 작업.
형태학적 연산은 이웃 연산으로 분류된다.
이러한 함수는 nppim 라이브러리에서 찾을 수 있다.
선형 이미지 변환.
함수는 nppist 라이브러리에 있다. 사용하는 하위 라이브러리에만 연결하면 동적 라이브러리를 사용할때 링크시간, 애플리케이션 로드 시간 및 CUDA 런타임 시작 시간을 크게 절약할수 있다.
Cuda에서 메모리는 크게 Host, Device로 나뉜다.
Host는 Cuda를 호출하는 기기, 윈도우 환경에서는 PC의 메모리 공간을 Host 메모리라고 하고, Cuda가 동작하는 Nvidia 기기, GPU를 Device 메모리라고 한다.
npp의 Label 마커는 라벨링 까지만 수행 하는것 같다. 통상의 블랍에서 사용하는 위치, 폭, 높이, 무게중심 등은 추가 처리를 해야하는 것 같다.
요즘 프로젝트에서 자주 사용하는 구성은 WPF UI에 C++ DLL로 프로세싱 구성을 한다.
이 방법이 장비 프로그램의 유연성과 호환성은 좋지만 C#에서 C++ DLL을 호출하는 인터페이스를 구성할 때 자료 구조를 매칭시켜줘야한다.
또한 C#과 C++간의 호출 시 마샬링의 오버헤드가 0는 아니기에 가급적 적은 횟수의 DLL 함수를 호출하는게 어플리케이션 성능 최적화에 도움이 된다. 단일 값을 받아오기보다는 데이터를 묶어서 한번에 받아오는 방식이 유리한 것 같다.
연결된 영역을 특정 새로운 값으로 채운다.
사용 가능한 컴퓨터 비전 함수들이다.
중심이 \(\textcolor{Black}{(x_c,y_c)}\) 이고, 반지름이 R인 원의 방정식은
‘Visual C++ 영상 처리 프로그래밍’에 있는 레이블링(블롭) 알고리즘을 정리한다.
TCP/IP 공부를 하면 크게는 동기 통신 이후 비동기 통신을 배우는 그 다음이 윈도우는 IOCP, 리눅스는 epoll이다. 간단히 말해 통신자체는 비동기로 수행을 하고(Non-Blocked), 결과확인을 IO쓰레드에서 전담한다는 것이다.