GN⁺: Rust에 Cranelift 코드 생성 도입
(lwn.net)- Cranelift는 Apache-2.0 라이선스의 코드 생성 백엔드로, WebAssembly를 위한 Wasmtime 런타임의 일부로 개발됨
- 2023년 10월, Rust 프로젝트는 Cranelift를 nightly 툴체인의 선택적 컴포넌트로 제공하기 시작
- 사용자들은 이제 Cranelift를 Rust로 작성된 프로젝트의 디버그 빌드를 위한 코드 생성 백엔드로 사용할 수 있음
- Cranelift는 기존 컴파일러와 경쟁하며, 중요한 최적화만을 우선시하는 간소화된 설계로 더 빠르게 코드를 생성함
컴파일 시간의 중요성
- 프로그래밍 언어 사용자들은 빠른 컴파일 시간을 원함
- Rust는 LLVM을 사용하는 다른 언어들과 마찬가지로 컴파일 시간에 대한 불만이 있었음
- 충분히 빠르게 코드를 생성하는 컴파일러는 인터프리터를 사용하는 것보다 유리할 수 있음
- 컴파일 속도에 중점을 둔 컴파일러는 가치가 있을 수 있음
Cranelift의 최적화
- Cranelift는 코드 생성 시 여러 방식으로 최적화를 수행함
- 최적화 파이프라인은 E-graphs를 기반으로 하며, 이는 중간 표현들의 집합을 효율적으로 나타내는 데이터 구조임
- 전통적인 컴파일러에서 최적화 순서는 생성된 코드의 품질에 큰 영향을 미침
- Cranelift는 E-graph를 사용하여 최적화 순서가 결과에 영향을 미치지 않도록 함
- E-graph에서 최종 표현을 추출하는 것은 NP-complete 문제이지만, Cranelift는 휴리스틱을 사용하여 충분히 좋은 표현을 빠르게 추출함
Rust를 위한 Cranelift
- Cranelift를 Rust 백엔드로 사용하기 위한 노력이 상당했음
- Rust 컴파일러는 mid-level IR을 사용하여 타입 체크된 프로그램을 표현함
- Cranelift를 사용하기 위해서는 mid-level IR을 CLIF로 변환하는 라이브러리가 필요했음
- 이 라이브러리는 Rust 컴파일러 팀 멤버인 "bjorn3"에 의해 주로 작성됨
- 사용자들은 rustup과 cargo를 사용하여 Cranelift 백엔드를 시험할 수 있음.
GN⁺의 의견
- Cranelift의 도입은 Rust 커뮤니티에서 컴파일 시간 단축에 대한 지속적인 요구에 대한 응답으로 볼 수 있음. 이는 개발자들의 생산성 향상에 기여할 수 있음.
- Cranelift가 E-graphs를 사용하여 최적화 순서 문제를 해결하는 접근 방식은 컴파일러 설계에 있어 새로운 패러다임을 제시함. 이는 컴파일러 연구 및 개발에 새로운 방향을 제시할 수 있음.
- 비판적인 관점에서 볼 때, Cranelift가 LLVM에 비해 얼마나 안정적이고 효율적인지는 아직 더 많은 실제 사용 사례를 통해 검증될 필요가 있음.
- Cranelift와 유사한 기능을 제공하는 다른 컴파일러 백엔드로는 GCC의 libgccjit 등이 있으며, 이러한 대안들과의 비교를 통해 Cranelift의 장단점을 더 명확히 파악할 수 있음.
- Cranelift를 도입하는 개발자들은 기존의 LLVM 기반 인프라와의 호환성 및 전환 비용을 고려해야 하며, Cranelift의 성능과 안정성을 면밀히 평가해야 함.
Hacker News 의견
- 백엔드와 최적화는 서로 다른 크레이트(crates)에 대해 다르게 사용할 수 있음. 의존성에 대해서는 최적화된 LLVM 빌드를 사용하고, 자신의 코드에 대해서는 디버그 LLVM이나 Cranelift를 사용하는 것이 종종 의미가 있음.
- 최적화 속도 대 최적화 품질에 대한 훌륭한 개요를 제공하는 기사. 특히, 사전 컴파일된 코드를 사용하는 복사-패치 컴파일이 여전히 가장 빠르지만 최적화에는 여지가 적음. Cranelift는 IR에서 동등성을 나타내기 위해 e-graphs를 사용하여 복사-패치 접근법보다 더 많은 최적화를 가능하게 함. 가장 최적화된 출력은 LLVM이나 GCC와 같은 전통적인 컴파일러 툴체인에서 나오겠지만, "충분히 빠른" 출력을 가능한 빨리 얻고자 하는 사용자들에게는 새로운 컴파일러 기술이 유망한 대안을 제공함.
- 전체 디버그 빌드에 대한 많은 댓글이 있지만, 작은 변경 사항에 대한 증분 빌드 시간이 가장 중요한 차이라고 생각함. 이것이 개발 반복을 가속화하는 것임. rust-analyzer와 gleam 프로젝트에서 작은 변경을 한 후의 빌드 시간을 비교했을 때, Cranelift와 mold를 추가한 경우가 훨씬 빠른 개선을 보임. Go 언어로 빌드된 Terraform과 비교해도 Rust의 큰 개선 사항을 보여줌.
- M1-M3 Mac 지원이 현재 없고 Windows 지원도 없는 것 같음. 가장 활발한 기여자의 최신 업데이트가 결론이 모호함. Windows 지원은 현재 생략되었고, macOS는 현재 x86_64만 지원함. M1 프로세서를 사용하는 경우 x86_64 버전의 rustc를 설치하고 Rosetta 2를 사용해 볼 수 있지만, Rosetta 2는 성능에 영향을 줄 수 있으므로 LLVM 백엔드와 비교해 봐야 함.
- Bevy 프로젝트에서 기사의 지침을 시도해 보고 "정상" 빌드와 비교함. Cranelift+debug 빌드와 비교해 릴리스 빌드가 빠른 것처럼 보이지만, sccache와 로컬 NAS를 사용해 캐싱하기 때문임. 캐싱 없이 디버그 빌드만 다시 시도했을 때, 컴파일 시간이 절반 가까이 줄어듦.
- Equality Graphs 링크를 통해 ESC/Java를 발견함. ESC/Java를 실제로 시도해 보거나 성공한 사람이 있는지 궁금함. Spot bugs(이전에는 Findbugs로 알려짐)와 비교해 보는 것이 흥미로움.
- Cranelift를 사용한 디버그 빌드가 개발 반복 속도를 높여줄 것에 대해 매우 기대됨. 특히 WASM/Frontend Rust에서 반복 속도가 중요한데, Rust 도구의 새 시대가 때때로 1초 미만의 빌드를 제공함. 아직 ARM macOS를 지원하지 않아 M1-3 사용자는 조금 기다려야 함.
- Cranelift를 사용했을 때의 런타임(컴파일 시간이 아닌) 벤치마크가 있는지 궁금함. 기사에서 "두 배 느림"이라고 언급되었지만, 그 데이터는 2020년 기준임. 그 이후로 상당히 개선되었는지 궁금함.
- Cranelift가 LLVM보다 빠를 것으로 예상되는 이유와 그 개선 사항이 LLVM에도 적용될 수 없는 이유를 설명해 줄 수 있는 사람이 있는지 궁금함.