VLC 가우시안 블러 필터를 C와 C#으로 경주시켜봤다
원제 C vs. C#: racing VLC's Gaussian blur
112 포인트댓글 34

Key Point
C# .NET AOT는 CPU 집약적 비디오 필터에서 C 대비 8~10% 수준으로 경쟁력 있으며, 컴파일러 최적화로 격차를 더 줄일 수 있다는 점이 주목할 만하다.
핵심 요약
- VLC 4의 가우시안 블러 필터를 C 원본과 C# 포트의 성능 비교하기 위해 동일한 환경에서 테스트했다.
- 라인 바이 라인 포트에서 C# 버전은 약 23% 더 느렸는데, 원인은 가비지 컬렉터가 아니라 RyuJIT 코드 생성기가 Math.Min을 매 루프마다 재계산하기 때문이다.
- 루프 경계를 사전 계산하고 nint 인덱스를 사용하는 두 줄의 수정으로 C# 성능을 8% 범위 내로 개선했다.
- 동일한 최적화를 양쪽에 적용했을 때 C# 버전은 2.5배 더 빨라졌으며, C는 여전히 약 24% 빨랐다.
- 분할 가능 알고리즘(행 블러 후 열 블러)을 활용하고, 나눗셈을 곱셈으로 대체하며, 대칭성을 활용한 최적화를 적용했다.
- 경계를 따로 처리하고 SIMD 없이도 현재 VLC 코드의 2.5배 성능을 달성했다.
- AVX2 SIMD 내재함수로 양쪽을 완전히 최적화했을 때 C#은 sigma 2·4에서 동등하게, sigma 8에서 9% 더 느렸다.
- 최종 결과: 1080p 1코어 기준 현재 VLC(8fps) → 라인 바이 라인 포트(6fps) → 최적화(20fps) → SIMD 튜닝(236fps).
- C# 성능 격차는 주로 컴파일러 차이에서 비롯되었고, 가비지 컬렉터와 경계 검사는 raw 포인터와 AOT 컴파일로 완전히 제거했다.
- 실험 과정에서 VLC의 두 가지 버그를 발견했다: 하드웨어 디코딩 시 CPU 필터로 화면 절반이 녹색으로 변하는 문제와 각 라인의 우측 가장자리 너머 2바이트를 읽는 문제다.
- .NET의 실험적 NativeAOT-LLVM 브랜치는 현재 WebAssembly만 지원하기 때문에 데스크톱 VLC 플러그인으로는 사용할 수 없다.
- 결과 코드는 VLCLR.Filters 라이브러리에 포함되어 모든 최적화 버전을 실행할 수 있다.