[IT 심층 분석]
카메라 ISP 이미지 프로세싱 파이프라인 구간의 메모리 병목 현상과 버퍼 언더런 해결 과정
김민준 · IT 시스템 엔지니어|
최근 차세대 모바일 단말기의 카메라 모듈 성능을 검증하는 과정에서 매우 까다로운 메모리 병목 현상에 직면했습니다. 문제의 핵심은 4K 해상도 비디오 레코딩을 60프레임으로 지속할 때 발생하는 간헐적인 프레임 드랍이었습니다. 초기 증상은 시스템 하드웨어의 열 스로틀링이나 커널 스케줄러의 타임 슬라이스 배분 문제로 추정되었으나 전체적인 시스템 자원 리소스 지표를 면밀히 분석한 결과 코어 클럭이나 온도는 전혀 임계점에 도달하지 않았습니다. 오히려 디바이스 트리의 메모리 맵이나 커널 로그를 파헤쳐보니 ISP 즉 이미지 시그널 프로세서가 버퍼 구조를 다루는 방식 자체에서 파생된 소프트웨어적 버퍼 언더런 현상이었음을 알게 되었습니다.
문제가 발생한 환경은 YUV 포맷의 이미지를 처리하기 위해 메모리 관점에서 DMA(Direct Memory Access) 방식을 차용한 커스텀 리눅스 커널 기반의 시스템이었습니다. 일반적인 영상 처리 루틴에서는 센서가 모은 빛 정보가 RAW 데이터로써 버퍼에 쌓이고 이후 ISP가 이를 넘겨받아 노이즈 감소나 화이트 밸런스 조정 등의 광학적 후처리를 진행해야 합니다. 60프레임 영상의 경우 1프레임당 주어지는 가용 연산 시간은 대략 16밀리초 남짓입니다. 만약 어떤 이유로든 이 16밀리초 안에 이전 프레임에 대한 메모리 해제와 다음 프레임의 할당이 맞물려 처리되지 않으면 필연적으로 병목이 누적되며 프레임 드랍으로 이어집니다.
추적을 위해 v4l2 커널 드라이버 소스 내 디버그 플래그를 모두 켜고 스트레이스(strace)와 퍼프(perf) 도구를 동원해 커널 스페이스에서의 시스템 콜 오버헤드를 측정했습니다. 놀랍게도 시스템 로그 상에서 메모리 할당 함수인 kmalloc 내지는 vmalloc을 호출할 때 평시 대비 10배 이상의 지연이 발생하고 있는 구간을 발견했습니다. 이는 프레임 버퍼가 연속된 물리 메모리를 요구하는 상황에서 메모리 단편화 현상이 극심하게 발생해 연속된 공간을 찾기 위해 리눅스 커널의 페이지 회수(Page Reclaim) 루틴이 강제로 동작했기 때문이었습니다. 즉 4K RAW 데이터라는 거대한 청크를 위한 메모리 공간을 실시간으로 요구하는데 단편화로 인해 파이프라인의 DMA 버퍼 할당 속도가 이를 따라가지 못했던 것입니다.
이 난제를 돌파하기 위해 프레임이 생성될 때마다 동적으로 메모리를 할당하는 기존의 레이지 로딩 방식의 아키텍처를 전면적으로 재설계했습니다. 카메라 애플리케이션 데몬이 부팅 초기나 모듈 초기화 단계에서 최대 예상 소요량에 달하는 방대한 크기의 연속된 물리 리저브드 메모리 영역(Reserved Memory Region)을 확보하도록 디바이스 트리를 수정했습니다. 그리고 DMA-BUF 프레임워크를 기반으로 사용자 영역과 커널 영역을 오가는 제로 카피 메커니즘을 보다 엄격하게 적용하여 메모리 포인터만을 교환하는 링 버퍼 매니저를 별도로 구현했습니다. 이렇게 구조를 변경하자 ISP가 필요로 하는 버퍼는 단편화의 영향을 받지 않는 독립된 공간에서 포인터 단위로 즉각 순환될 수 있었으며 시스템 콜로 인한 오버헤드는 사실상 영공에 가깝게 수렴했습니다.
최종적으로 커널 컴파일을 다시 진행하고 수정된 바이너리를 플래싱한 뒤 부하 테스트 시나리오를 다시 구동했습니다. 4K 60fps 비디오 레코딩을 세 시간 연속으로 진행하면서 내부 버퍼 큐의 상태를 실시간 로깅으로 모니터링했는데 단축된 메모리 접근 시간 덕분에 단 1프레임의 손실도 발생하지 않았음을 확인했습니다. 이번 트러블슈팅 경험은 메모리 단편화라는 고전적인 운영체제의 본질적 결함이 고성능 카메라 시스템 파이프라인에 얼마나 치명적인 영향을 끼칠 수 있는지 여실히 보여주는 사례였습니다. 단순히 스펙 상의 하드웨어 성능만 믿고 메모리 할당 전략을 기본 커널 루틴에 온전히 의존해서는 한계에 봉착할 수밖에 없음을 뼈저리게 느꼈습니다.