VLC 가우시안 블러를 C#으로 한 줄씩 포팅해보니 C보다 23% 느림, 두 줄 고쳐 8% 차이까지 좁혀
- VLC의 gaussianblur.c를 Native AOT로 한 줄씩 C#으로 포팅해 같은 VLC 4 릴리스 빌드, 같은 1080p 프레임에서 비교한 결과 sigma 4 기준 프레임당 155.2ms로 C의 125.9ms보다 약 23% 느림
- 원인은 RyuJIT이 루프 경계의 Math.Min을 매 스텝 다시 계산하고 누적 합을 레지스터 대신 메모리에 두는 데 있으며, 루프 경계를 로컬 변수로 빼고 인덱스를 nint로 바꾸는 두 줄 수정만으로 C와의 차이가 8%까지 줄어듦
- 가우시안 블러는 분리 가능(separable)해서 25x25 창의 625회 곱셈이 25회짜리 두 패스로 줄고, VLC는 2007년부터 정수 연산으로 이를 구현해 옴
- C# 필터는 프레임마다 관리 힙에 아무것도 할당하지 않아 실행 중 GC가 수집할 대상이 없음
- 토론에서는 원본 VLC 필터가 SIMD를 쓰지 않는 점과 CPU 대신 GPU 셰이더로 돌렸어야 한다는 점이 나왔고, O(n) 블러 알고리즘과 시그마별 변형 유지보수 부담도 논의됨
Hacker News 의견들
AOT로 컴파일해보고 싶은 C# 프로젝트가 있었는데 성능이 C에 거의 붙는다니까 동기부여가 되네. 복잡한 프로그램은 사정이 다르겠지만.
근데 왜 굳이 AOT를 써? 시작 시간이나 네이티브 상호운용에는 좋은데, 기계별 최적화를 못 살려서 전반적으로는 더 느릴 수도 있는데 말이야.
8%면 산업계 기준으로는 산 하나 차이임. 회사 이익률보다 큰 폭이라고.
8% 우유는 맛없고 요리도 망치겠네. 숫자 카테고리가 완전히 다른 걸 비교하고 있잖아. 실제 사업에서는 프로젝트 한 단계가 몇 퍼센트 빨라지는 게 매출에 거의 영향이 없고, CPU 시간 아끼는 건 더 중요하지도 않아.
글이 재밌네. 근데 원본 VLC 필터가 SIMD를 안 쓴다는 게 제일 놀랍다. 최신 CPU 사놓고 새 기능은 아무 소프트웨어도 안 써먹으니까 돈이 아깝다는 생각이 들어.
난 CPU에서 도는 것 자체가 놀랍다. 필터면 GPU 셰이더로 돌 줄 알았는데. 20년 전에 GLSL로 2패스 가우시안 블러 짠 기억이 있는데.
맞아 빨리 하려면 GPU가 답이지. 4K 넘어가면 특히 심하고. 아라스가 쓴 fast blur 글도 참고해봐.
가우시안 블러에는 O(nσ) 대신 O(n)으로 도는 더 빠른 알고리즘도 있음. ipol.im 서베이 논문 한번 봐.
FFT 블러 같은 건 O(n)이라 좋아 보여도 FFT랑 iFFT 오버헤드가 붙어. 시그마에 따라 어떤 건 빠르고 어떤 건 느려서 경우별로 변형을 두고 전환도 부드럽게 해야 하고, 큰 시그마는 10픽셀마다 건너뛰는 근사도 써야 함. 거기에 SIMD랑 캐시 동작까지 붙이면 아키텍처별로 십수 개 버전을 유지보수해야 되는데, 대체 목표 이득이 뭐냐는 거지.
C# 버전이 unsafe 포인터를 쓴다면서? 그럼 사실상 C로 짠 거나 마찬가지라 결과가 비슷하게 나온 게 하나도 안 놀랍네.