GN⁺: FFMpeg, 손으로 작성한 AVX-512 어셈블리 코드로 94x 성능 향상
(twitter.com/FFmpeg)- 현대의 고급 프로그래밍 언어와 고급 컴파일러는 소프트웨어 개발을 크게 단순화하고 비용을 낮추지만, API의 비효율성으로 인해 현대 하드웨어의 성능 기능을 숨기는 경향이 있음
- FFmpeg 개발자들에 따르면, 어셈블리 코드를 사용하면 워크로드에 따라 성능이 3배에서 94배까지 향상될 수 있음
- FFmpeg 내의 특정 기능을 가속화하기 위해 AVX-512 명령어 세트를 사용하여 최적화된 코드 경로를 만들었고, 표준 구현에 비해 훨씬 더 빠른 성능을 달성할 수 있었음
- AVX-512는 512비트 레지스터를 사용하여 단일 정밀도 FLOP 16개 또는 배정밀도 FLOP 8개를 한 번의 연산으로 처리할 수 있어 대량의 데이터를 병렬로 처리할 수 있음
- 벤치마킹 결과에 따르면 새로운 수작업 AVX-512 코드 경로가 기준 C 코드, AVX2 및 SSE3와 같은 낮은 SIMD 명령 집합을 포함한 다른 구현보다 상당히 빠름
- 이 개발은 AVX-512 지원 하드웨어에서 실행되는 사용자에게 특히 유용하며 미디어 콘텐츠를 훨씬 더 효율적으로 처리할 수 있음
- 그러나 인텔은 12세대, 13세대, 14세대 코어 프로세서에서 AVX-512를 비활성화하여 이러한 CPU의 소유자들이 이를 사용할 수 없게 됨
- 반면 AMD의 Ryzen 9000 시리즈 CPU는 완전히 활성화된 AVX-512 FPU를 특징으로 하므로 이러한 프로세서의 소유자는 FFmpeg의 성과를 활용할 수 있음
- 아쉽지만, AVX-512의 복잡성과 특수성으로 인해 이러한 최적화는 일반적으로 성능이 중요한 애플리케이션에 국한되며 저수준 프로그래밍 및 프로세서 마이크로아키텍처에 대한 전문 지식이 필요함
( 이 내용은 Tom's Hardware의 FFmpeg devs boast of up to 94x performance boost after implementing handwritten AVX-512 assembly code 에서 가져옴 )
예전에 관련 작업을 잠깐 해본 경험이 있어서 말씀드리면 일단 94라는 것은 어그로입니다.
의견에 올라온대로 스칼라/벡터 코드의 차이로 성능 차이가 크게 나타난 것입니다.
하지만 대부분의 상업용 코덱은 어셈블리 코딩으로 최적화를 수행합니다.
"대부분의 C코드는 최적의 어셈블리 코드로 컴파일됨"이 맞는 말이긴 합니다만 성업용 제품을 개발하기 위해서는 그 대부분의 수준보다 높아야되니까요. 특히 임베디드쪽에서는 더 중요합니다.
Hacker News 의견
- FFmpeg의 특정 필터에서 성능이 94배 향상되었다는 주장은 오해의 소지가 있음. 대부분의 사용자는 이미 AVX/SSE를 사용하고 있었기 때문에 C 코드 최적화가 필요하지 않았음
- FFmpeg의 주요 CPU 사용자는 인코딩과 디코딩이며, 이번 개선은 이에 영향을 미치지 않음
- 손으로 작성한 어셈블리 코드와 그렇지 않은 코드의 비교가 아닌, 스칼라 코드와 벡터 코드의 비교임
- AVX 내장 함수를 사용하여 C 코드를 작성하면 어셈블리 코드 없이도 유사한 속도 향상을 얻을 수 있음
- 특정 경우에는 손으로 작성한 어셈블리 코드가 유리할 수 있음
- 비디오 디코더는 매우 타이트한 루프를 포함하고 있어, 성능의 일관성을 유지하기 위해 어셈블리 코드가 필요함
- FFmpeg 팀은 내장 함수 사용을 금지하고 모든 플랫폼별 코드를 어셈블리로 작성하도록 요구함
- 어셈블리 코드는 충분한 노력을 기울이면 항상 더 빠르지만, 내장 함수는 적은 노력으로도 매우 가까운 성능을 얻을 수 있음
- 94배 향상은 dav1d의 최적화이며, FFmpeg뿐만 아니라 다른 프로그램에서도 사용할 수 있음
- RISC-V(64비트) 최적화에 대한 요청이 있으며, 관심 있는 사람들에게 좋은 기회임
- LuaJIT의 Mike Pall은 어셈블리 코드 작성의 이점을 설명한 바 있음
- 마이크로 벤치마크에서 단일 함수가 C 코드보다 94배 빨라짐
- Intel은 Core 12, 13, 14세대 프로세서에서 AVX-512를 비활성화함
- 이에 대한 명확한 이유는 찾지 못했음
- 성능 문제 해결 전에 병목 현상을 식별하는 작업이 충분히 이루어지지 않는 경우가 많음
- 대부분의 C 코드는 최적의 어셈블리 코드로 컴파일됨
- 성능 향상의 원인은 손으로 작성한 어셈블리 코드가 아닌 AVX-512 SIMD 명령어 사용임
- gcc의 AVX-512 벡터화와 비교해보고 싶음
해당 이유보다는 E코어가 AVX-512를 지원하지 않다보니, 소프트웨어적으로 막아둔걸로 압니다.
P코어는 비공식적으로 AVX-512 지원했었어요.