기타 Lobsters · 2026-09-22

"하스켈에서도 어셈블리 쓰고 싶다고!" 하스켈로 인라인 어셈블리 흉내 내는 개발자의 광기

핵심 요약
  • C/C++과 달리 인라인 어셈블리 기능이 없는 하스켈(GHC)에서 특수 CPU 명령어를 직접 호출하기 위한 저수준 우회 기법이 공유되었습니다.
  • GHC의 C FFI가 구조체 값 반환을 지원하지 않는 한계를 극복하기 위해 포인터 메모리 할당과 unsafePerformIO를 조합해 64비트 정수 2개의 128비트 곱셈 결과를 얻어냈습니다.
  • 고수준 순수 함수형 언어에서 하드웨어 레지스터와 저수준 최적화를 극한으로 쥐어짜 내기 위한 독특한 프로그래밍 실험입니다.
요약 함수형 언어 하스켈(Haskell)의 컴파일러인 GHC 환경에서 어떻게든 인라인 어셈블리처럼 특정 CPU 명령어를 직접 호출하고 복수 반환값을 처리해 보려는 괴짜 개발자의 기술 분석글이 화제입니다. 최신 CPU에는 SIMD, 암호화 연산 등 특정 작업에 특화된 명령어가 많아 C/C++에서는 인라인 어셈블리나 내장 함수(intrinsics)를 통해 이를 손쉽게 활용할 수 있습니다. 반면 하스켈(GHC)에는 인라인 어셈블리를 직접 작성할 수 있는 기본 문법이 없어 저수준 CPU 명령어를 끌어다 쓰기가 까다롭습니다. 작성자는 64비트 정수 2개를 곱해 상위 64비트와 하위 64비트(총 128비트)를 모두 얻어내는 연산을 예시로 삼아 이를 해결하는 실험을 진행했습니다. x86 어셈블리 레벨에서는 `mulq` 명령어로 상·하위 비트가 한 번에 계산되지만, 하스켈의 일반적인 곱셈 연산자로는 하위 64비트만 계산할 수 있기 때문입니다. C 언어에서는 `__int128`이나 구조체 값 반환을 통해 128비트 결과를 레지스터 수준에서 효율적으로 돌려받을 수 있지만, 현재 하스켈의 C FFI(Foreign Function Interface)는 구조체를 값(by-value)으로 전달하거나 반환하는 기능을 지원하지 않는 한계가 있습니다. 이에 작성자는 C 코드에서 포인터를 인자로 넘겨 상위 비트를 받아오고, 하스켈 측에서 `unsafePerformIO`와 메모리 할당(`alloca`, `peek`)을 활용해 포인터로 값을 꺼내 순수 함수로 감싸는 방식을 시도해 결과를 검증했습니다. 하스켈 생태계 특유의 고수준 추상화를 뚫고 어떻게든 기계어 레벨 성능과 명령어를 쥐어짜 내려는 집념이 돋보이는 테크니컬 삽질기입니다.
Sponsored · 광고