GN⁺: 150줄의 C 코드로 NumPy 행렬 곱셈 능가
(salykova.github.io)요약
소개
- 행렬 곱셈은 현대 신경망에서 필수적인 요소임
- NumPy는 외부 BLAS 라이브러리를 사용하여 고성능을 달성함
- 이 글에서는 간단하고 이식 가능하며 확장 가능한 고성능 행렬 곱셈을 구현하는 방법을 설명함
NumPy 성능
- NumPy는 AMD CPU에서 OpenBLAS를 사용함
- 성능 측정은 FLOP/s로 계산됨
- Ryzen 7 7700 CPU에서 NumPy의 단일 스레드 및 다중 스레드 성능을 측정함
이론적 한계
- CPU의 메모리 계층 구조와 SIMD 확장을 설명함
- 이론적으로 단일 스레드에서 163 GFLOPS, 다중 스레드에서 1203 GFLOPS를 달성할 수 있음
단순 구현
- 기본적인 행렬 곱셈 알고리즘을 설명하고, 단순 구현의 성능을 측정함
- 단순 구현은 2.7 GFLOPS를 달성함
커널
- 행렬 곱셈을 작은 하위 문제로 분할하여 해결하는 방법을 설명함
- SIMD 명령어를 사용하여 커널을 최적화함
- 16x6 커널을 사용하여 147 GFLOPS를 달성함
마스킹 및 패킹
- 임의의 행렬 크기를 처리하기 위해 경계 케이스를 다루는 방법을 설명함
- 마스킹과 패킹을 사용하여 성능을 최적화함
- 새로운 구현은 56 GFLOPS를 달성함
캐싱
- CPU 캐시의 메모리 시스템을 설명함
- 캐시를 활용하여 데이터 재사용과 캐시 관리를 최적화함
GN⁺의 의견
- 이 글은 고성능 행렬 곱셈을 구현하는 방법을 단계별로 설명하여 매우 교육적임
- SIMD 명령어와 CPU 캐시를 활용한 최적화 방법을 배울 수 있음
- NumPy와 같은 라이브러리의 내부 동작을 이해하는 데 도움이 됨
- 유사한 기능을 가진 다른 프로젝트로는 Intel MKL, OpenBLAS 등이 있음
- 새로운 기술이나 오픈 소스를 채택할 때는 성능과 이식성을 고려해야 함
Hacker News 의견
-
대부분의 소프트웨어는 최적화되지 않아 성능 향상 여지가 많음
- 알고리즘 선택이 가장 중요함
- 커널 호출과 같은 무거운 작업을 줄일 수 있는지 확인 필요
- 벡터화를 통해 성능 향상 가능
- 캐시 효율성을 최적화할 수 있는지 확인 필요
- 하드웨어에 특화된 최적화 가능성 검토 필요
-
BLIS 레포지토리에 참조된 논문들은 이 주제를 이해하는 데 권위 있는 자료임
- 최적화된 BLAS가 성능이 좋지 않다고 생각하는 이유를 이해하지 못함
- numpy 대신 AMD의 BLAS를 사용해야 함
- BLIS는 OpenBLAS보다 병렬화가 더 잘 되어 있음
-
SIMD 명령어는 마이크로 커널 벡터화에 필요하지 않음
- 적절한 블록 크기를 사용하면 BLIS의 순수 C 마이크로 커널이 손으로 최적화된 구현의 80% 이상의 성능을 발휘함
-
대부분의 코딩 패턴은 하드웨어에 완전히 특화되지 않아 많은 성능을 놓치고 있음
- "There's plenty of room at the top"이라는 CS 클래식 논문을 참조할 만함
-
벤치마크를 쉽게 반복할 수 있게 한 점이 칭찬받을 만함
- 16코어 Xeon CPU에서 matmul.c가 gcc -O3로 컴파일 시 1.41초, clang -O2로 컴파일 시 1.47초, NumPy는 1.07초 걸림
- avx512 커널이 더 빠를 것이라고 믿음
- omp 대신 pthreads를 사용해 스레드 풀을 명시적으로 관리하면 오버헤드를 줄일 수 있음
-
numpy의 구현이 실제로 멀티스레딩을 사용하는지 의문임
-
OpenBLAS보다 성능이 좋은 이유가 궁금함
- 캐싱 등 세부 사항을 다루고 있음
- 특정 프로세서에 더 최적화된 것인지 궁금함
-
한쪽은 Python, 다른 쪽은 C로 비교하는 것은 공정하지 않음
- 둘 다 C로 작성하여 비교하는 것이 더 나음
-
마스크 생성의 비효율성이 신경 쓰임
- 더 효율적인 방법으로 글로벌 상수 배열을 생성하거나 상수 벡터와 비교하는 방법이 있음
- 하지만 이는 사소한 문제이며, 실제로는 큰 차이가 없을 것임
-
행렬 곱셈 자체를 멀티스레딩하는 것의 실용성에 의문을 가짐
- 멀티스레딩은 행렬 곱셈을 사용하는 알고리즘에 더 유용할 것임
-
jart의 tinyBLAS에 대한 언급
- 관련 링크 제공