CRuby에서 더 빠른 FFI를 위한 Tiny JIT

Tiny JITs for a Faster FFI

작성자
발행일
2025년 02월 12일

핵심 요약

  • 1 CRuby의 FFI는 네이티브 코드 호출 시 C 확장보다 성능 오버헤드가 커서 병목 현상을 유발합니다.
  • 2 FJIT(FFI JIT)는 FFI 호출에 필요한 머신 코드를 런타임에 JIT 컴파일하여 오버헤드를 줄이는 새로운 접근 방식입니다.
  • 3 FJIT는 기존 FFI보다 2배 이상 빠르고 C 확장과 유사하거나 더 나은 성능을 보여, Ruby의 네이티브 코드 호출 효율성을 크게 향상시킬 잠재력을 가집니다.

도입

루비(Ruby) 개발 시 네이티브 코드 호출이 필요할 때, FFI(Foreign Function Interface)는 C 확장에 비해 성능 오버헤드가 커서 병목 현상을 야기합니다. 본 문서는 CRuby의 FFI 성능을 개선하고, 네이티브 코드 호출 효율성을 극대화하기 위한 'Tiny JIT' 접근 방식의 개념과 그 가능성을 제시합니다.

이 글은 strlen 함수 벤치마크를 통해 FFI, C 확장, 루비 내장 메서드의 성능을 비교한 결과, FFI가 가장 느려 상당한 오버헤드를 보였습니다. 이에 저자는 FFI 래퍼 함수 정의 시 필요한 머신 코드를 JIT 컴파일하는 아이디어를 제안합니다. 이는 attach_function에서 얻는 정보를 활용하여 런타임에 최적화된 머신 코드를 생성하는 방식입니다. 이를 위해 머신 코드 생성(AArch64, Fisk), 실행 가능한 메모리 할당(JITBuffer), 그리고 루비가 생성된 머신 코드로 점프하도록 유도하는 RJIT의 역할이 필수적입니다. 특히 RJIT가 Gem으로 추출되면 서드파티 JIT 컴파일러 개발이 용이해져, FJIT(FFI JIT)와 같은 소규모 JIT 컴파일러가 FFI 오버헤드를 우회할 수 있습니다. 개념 증명으로 개발된 FJIT는 strlen 벤치마크에서 기존 FFI보다 2배 이상 빠르고 C 확장과 유사하거나 더 나은 성능을 보여주며, FFI의 성능 병목을 효과적으로 해결할 수 있음을 입증했습니다.

결론

FJIT의 개발은 "가능한 한 많은 루비 코드를 작성"하는 철학을 유지하면서도 C 확장과 동등하거나 그 이상의 네이티브 코드 호출 성능을 달성할 수 있는 고무적인 가능성을 제시합니다. 이는 루비의 활용 범위를 넓히고 성능에 민감한 애플리케이션 개발에 새로운 지평을 열 수 있습니다. 현재 ARM64 플랫폼 제한, 모든 파라미터/반환 타입 미지원 등 몇 가지 제약 사항이 있지만, 저자는 이러한 한계가 극복 가능하다고 강조하며, FJIT가 루비 FFI 성능을 혁신적으로 개선할 중요한 진전임을 시사합니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!