POOOLING FOREST
새로운 샌드박스 기술의 발견: LoongArch 에뮬레이터가 보여준 가능성 - Lua나 Wasm의 오버헤드를 극복할 대안으로 발견한 LoongArch 에뮬레이터 libloong. 4ns라
Engineering & Tech

새로운 샌드박스 기술의 발견: LoongArch 에뮬레이터가 보여준 가능성

Lua나 Wasm의 오버헤드를 극복할 대안으로 발견한 LoongArch 에뮬레이터 libloong. 4ns라는 경이로운 호출 성능과 샌드박스 기술로서의 가능성을 탐구합니다.

김영태

테크리드

안녕하세요. 풀링포레스트 테크리드 김영태입니다.

백엔드 시스템을 설계하다 보면 항상 마주치는 딜레마가 있습니다. 바로 '유연성'과 '안전성' 사이의 줄타기입니다. 최근 우리 팀은 서비스 내에서 특정 비즈니스 로직을 동적으로 업데이트해야 하는 요구사항을 마주했습니다. 서버 재배포 없이 로직을 갈아끼워야 하는 상황이었죠. 보통 이럴 때 Lua 같은 스크립트 언어를 내장하거나, 최근 유행하는 WebAssembly(Wasm)를 고려하곤 합니다. 하지만 막상 도입하려니 '호출 오버헤드'라는 벽이 생각보다 높더군요.

솔직히 말해, 처음엔 막막했습니다. Lua는 가볍지만 C++ 호스트와 통신할 때 발생하는 컨텍스트 스위칭 비용(약 150ns)이 고빈도 트래픽 처리에선 병목이 될 게 뻔했습니다. Wasm 런타임들은 무겁거나, JIT 예열 시간이 필요했죠. "그냥 컨테이너로 띄울까?" 싶었지만, 리소스 낭비가 심했습니다. 그러던 중, 우연히 `libloong`이라는 흥미로운 오픈소스 프로젝트를 발견하게 되었습니다.

이름에서 알 수 있듯이 이건 LoongArch(LA64) 아키텍처를 위한 사용자 공간 에뮬레이터입니다. 처음엔 "굳이 마이너한 아키텍처인 LoongArch 에뮬레이터를 우리가 왜?"라고 생각했습니다. 하지만 스펙을 뜯어보고 직접 벤치마크 결과를 확인한 뒤, 저는 머리를 한 대 맞은 기분이었습니다.

이 라이브러리의 핵심은 '극단적인 경량화'와 '속도'였습니다.

가장 충격적이었던 건 호스트와 게스트 간의 호출 오버헤드가 단 4ns에 불과하다는 점이었습니다. 일반적인 Lua VM이 150ns 정도인 걸 감안하면, 거의 함수 호출 비용이 없는 수준이나 마찬가지입니다. 게임 엔진에서 스크립팅 용도로 설계되었다고 하는데, 이 정도 성능이면 고성능 백엔드 로직을 격리(Sandboxing)해서 돌리는 데에도 손색이 없겠다 싶었죠.

코드를 한번 살펴볼까요? 사용법도 놀랍도록 직관적이었습니다. C++ 환경에서 외부 바이너리를 로드하고 실행하는 과정이 아주 깔끔합니다.

#include <libloong/machine.hpp>

int main() {
    // LoongArch ELF 바이너리를 로드합니다.
    std::vector<uint8_t> binary = load_file("program.elf");

    // 64MB 메모리를 할당하여 가상 머신을 생성합니다.
    loongarch::Machine machine{ binary, { .memory_max = 64 * 1024 * 1024 } };

    // 실행 인수를 설정합니다. (마치 리눅스 커맨드처럼)
    machine.setup_linux({ "program" }, { "LC_ALL=C" });

    // 샌드박스 환경에서 프로그램을 실행합니다.
    machine.simulate();
}

단순히 실행만 되는 게 아닙니다. 성능 지표도 인상적이었습니다. CoreMark 벤치마크 기준으로 인터프리터 방식임에도 불구하고 상당히 높은 점수를 뽑아냅니다. 여기에 경량 JIT를 켜면 네이티브 성능의 약 38%까지, 바이너리 변환(Binary Translation) 기능을 사용하면 네이티브의 77% 수준까지 성능이 올라갑니다.

저는 이 프로젝트를 보면서 기술 선택의 시야를 넓혀야 한다는 것을 뼈저리게 느꼈습니다. 우리는 흔히 x86이나 ARM, 혹은 Wasm 같은 주류 기술 안에서만 해답을 찾으려 합니다. 하지만 `libriscv`를 기반으로 검증된 아키텍처 위에, LoongArch라는 다소 생소한 명령어 집합(ISA)을 얹어 이렇게 효율적인 샌드박스를 만들어낸 사례는 시사하는 바가 큽니다.

물론 당장 프로덕션 메인 로직을 이걸로 전면 교체하겠다는 뜻은 아닙니다. 하지만 '안전하게', '아주 빠르게', '외부 코드를 실행'해야 하는 상황에서 이 라이브러리는 훌륭한 대안이 될 수 있습니다. 특히 Rust나 Go 바인딩도 지원하고 있어, 우리 팀처럼 다양한 언어를 사용하는 환경에서도 도입을 검토해 볼 만합니다.

개발자 여러분, 때로는 주류에서 살짝 벗어난 기술들이 의외의 돌파구가 되기도 합니다. "이건 내가 아는 아키텍처가 아닌데?" 하고 지나치기보다, 그 안에 담긴 엔지니어링의 정수를 들여다보는 습관을 가져보세요. 4ns의 오버헤드라는 숫자가 주는 전율을 느껴보셨으면 좋겠습니다.

앞으로도 풀링포레스트 팀은 이런 숨겨진 보석 같은 기술들을 발굴하고 검증하며, 더 효율적인 시스템을 만들기 위해 끊임없이 고민하겠습니다. 감사합니다.

지금 읽으신 내용, 귀사에 적용해보고 싶으신가요?

상황과 목표를 알려주시면 가능한 옵션과 현실적인 도입 경로를 제안해드립니다.