러스트 SIMD 라이브러리 fearless_simd 1.0 출시, unsafe 없이 인트린시크까지 안전하게
- 러스트용 SIMD 라이브러리 fearless_simd가 8년 만에 v1.0을 출시함. 자체 코드에 unsafe 블록을 쓰지 않고 SIMD를 구현했으며 다른 SIMD 추상화들의 수천 개 unsafe 블록과 비교됨
- kernel! 매크로가 target feature v1.1에 의존해 대부분의 SIMD 인트린시크를 unsafe 호출 없이 부르고, raw pointer를 다루는 로드·스토어는 bytemuck·zerocopy를 닮은 안전 트랜스뮤트 모듈로 처리함. 감사할 블록은 이 두 가지뿐임
- swizzle·부동소수점 max처럼 플랫폼마다 결과가 갈리는 연산은 정밀 변형과 빠른 변형을 함께 제공하고, 포터블 추상화에 없는 명령은 오버헤드 없이 플랫폼 인트린시크로 내려갈 수 있게 해 성능 상한을 없앰
- 함께 공개된 fearless_simd_macros v0.1의 #[simd] 매크로가 함수 멀티버전을 자동으로 처리해 #[inline(always)] 없이 최적 타깃 코드가 나온다고 설명함
- 논의에선 Fearless SIMD로 이식한 사용례가 보고됨. memchr-n은 바이트 집합 검색에서 rust memchr를, PhastFT는 std::simd 의존을 벗고 stable 러스트에서 동작을 확보함
Hacker News opinions
0.x 저주 드디어 뚫었네. 러스트 라이브러리는 기본값이 ZeroVer이라 1.0이 무지 반갑다
2018년 프로토타입 글 올라온 지 8년 만임. 그때부터 계속 다듬어온 작업이니 축하할만함.
SIMDeez도 직접 만들어본 사람인데, 이거 제대로 하려면 진짜 어렵다. 인트린시크를 플랫폼마다 안 쓰고 성능 뽑기가 쉬운 문제가 아니거든.
지금 Dart 쪽 SIMD 지원 넣는 중인데 질문 하나. f64가 NaN이 아닌 걸 알면 x86에선 min/max 하나, arm64에선 하나 추가로 끝나거든. 이런 걸 함수 간 분석으로 추적하는 언어가 있나?
없다고 봄. 근데 효과 과대평가한 듯. 부동소수점에서 0.0이나 NaN 여부를 미리 아는 건 상수 초기화 같은 극단적 케이스만 가능하고, 걔네는 컴파일 타임에 상수 폴딩됨.
패턴 타입이 nightly에 들어가 있고, 미래엔 'NaN 없는 f64' 같은 타입이 나올 여지도 있음. 다만 연산 후 값이 NaN으로 바뀌지 않게 체크가 붙어야 해서 오히려 최적화가 어려울 듯함.
커스텀 컴파일러 훅은 대부분 언어에서 지원 안 한다. 언어 자체가 바뀌는 문제라서. SBCL은 훅 있고 아마 Jai도 있고, LLVM 위에다 직접 짤 순 있음.
Fearless SIMD로 memchr-n 이라는 바이트 집합 검색 라이브러리 짜봤는데, memchr 크레이트보다 오히려 빠르더라. 집합이 1~3개여도 마찬가지고.
혹시 fearless simd 쓰기 전에 다른 포터블 SIMD 크레이트들도 비교해봤나?
std::simd가 아직 nightly라 못 쓰던 FFT 크레이트 PhastFT가 이제 stable 러스트로 돌아간다. 그 과정에서 필요 기능이 생기니 메인 기여자가 fearless_simd에 패치를 계속 밀어넣었고.
google/highway랑 설계 비교해주실 분 있나? 걔도 동적 디스패치 편하게 해주는데 같은 문제를 어떻게 풀었는지 궁금함.
f16까지 필요하면 macerator라는 선택지가 하나 더 있다.