TL;DR

  • 게임 엔진의 멀티스레드 입자 시뮬레이션을 모노모픽 TypeScript로 작성하고 동일한 로직의 Zig 코드로 미러링해 함수별로 교체하는 방식임.
  • 타입 배열의 원시 메모리 연산으로 단순화된 함수는 AI가 연산 순서와 메모리 읽기·쓰기를 유지하며 포팅하기 쉬움.
  • 함수에 따라 Zig 포팅 후 성능이 1~10배 향상되고, 패리티 단위 테스트가 동작 일치를 확인함.
  • 4,000개 입자에 묶여 있던 엔진이 M4 MacBook Air 개발 장비에서 연성체 SDF 충돌을 포함해 100,000개 입자를 안정적으로 처리함.
  • GPU 연산으로 옮기지 않고도 연간 65달러 서버에서 10,000개 단위 시뮬레이션을 편안하게 실행할 수 있음.

모노모픽 TypeScript로 구성한 시뮬레이션

  • Atwood의 법칙은 자바스크립트(JavaScript)로 작성할 수 있는 애플리케이션은 결국 자바스크립트로 작성된다는 주장임. 자바스크립트는 네이티브 코드와 비교해 원시 성능이 낮고, 웹어셈블리(WebAssembly)보다도 빠르지 않지만, 이 사례에서는 예상과 다른 결과가 나타남.
  • 구축 중인 게임 엔진의 백엔드는 엔티티 컴포넌트 시스템(ECS)을 기반으로 한 복잡한 멀티플레이어 입자-셀 시뮬레이션(PIC)으로, 입자와 필드로 구성됨.
  • 엔진은 대부분 TypeScript로 작성되고 일부는 Zig와 Rust를 혼합해 사용함. 복잡한 수학 연산과 휴리스틱은 멀티스레드 시뮬레이션 부분에 있으며 모노모픽 TypeScript로 작성됨.
  • 1년 넘게 전에 클래스 기반 코드 일부를 모노모픽 클로저 기반 TypeScript로 리팩터링하는 설계를 고안함. 이 방식은 더 최적화된 V8 기계어로 컴파일되며, 코드의 작업 편의성·간결성·성능·확장성을 함께 개선하는 더 큰 변경의 일부임.
  • 함수 일부를 작성하고 AI가 이를 V8 어셈블리로 컴파일해 적절성을 살펴본 뒤, 여러 코딩 스타일을 마이크로벤치마크로 비교하는 체계적인 과정을 거침.
  • 마이크로벤치마킹에 지나치게 빠져 실제 게임 메커니즘보다 엔진 휴리스틱과 미세 최적화에 시간을 쓰기도 했으며, 일부 최적화는 잘못된 방향으로 이어짐.

TypeScript 함수를 Zig로 미러링

  • 시뮬레이션 인스턴스의 규모만 충분하면 됐으므로 네이티브 성능보다 50~100% 느린 수준도 받아들일 생각이었음.
  • 리팩터링한 모노모픽 코드가 점차 분리되면서 각 함수의 메서드부터 최상위 함수까지, 타입 배열에 대한 원시 읽기·쓰기와 부동소수점 연산만으로 표현할 수 있게 됨.
  • 엔진은 대형 아레나 기반 자체 메모리 할당자와 자체 단편화 제거기, 커스텀 ECS를 사용하므로 시뮬레이션 함수는 해당 데이터에 대한 연산으로 구성됨.
  • 이 구조를 바탕으로 AI 에이전트에 각 TypeScript 함수를 Zig로 정확히 1대1 포팅하도록 요청함. 데이터 접근용 커스텀 클로저 헬퍼는 원시 배열 연산으로 펼치거나 인라인 함수로 별칭 처리함.
  • 개발 모드와 프로덕션에서 runResolvers 같은 함수를 runResolversNative 버전으로 바꿔 실행할 수 있음.
  • 일부 함수는 구현이 조금 다를 수 있음. 필드 솔버는 바이트 단위로 정확히 같은 출력을 내는 SIMD 경로를 사용하고, 일부 수학 유틸리티는 네이티브 측에서 조금 더 빠른 float32 연산을 위해 최적화된 컴파일 시점(comptime) 플래그를 사용함.

성능과 개발 방식

  • 무거운 함수를 벤치마크해 Zig로 포팅할 대상을 고름. Zig는 클로저 기반 사전 할당 메모리 패턴에 잘 맞음.
  • 미러링된 코드가 로직과 연산 순서, 메모리 읽기·쓰기를 동일하게 유지하므로 AI가 최소한의 추론으로 결정론적으로 포팅할 수 있음.
  • 포팅에 따른 성능 향상은 대상 함수에 따라 1~10배이며, 기본적인 패리티 단위 테스트와 결합해 AI를 CI/CD 파이프라인의 추가 최적화 트랜스파일러처럼 활용함.
  • 원본이 모노모픽 TypeScript 클로저와 타입 배열에 있으므로 Zig를 직접 작성할 필요가 없음.
  • TypeScript 코드는 간결하고 깔끔하며 프로토타이핑하기 쉬움. TypeScript 문법은 거의 없고 주로 린팅에 사용함.
  • 핫 모듈 교체(HMR)로 변경 사항을 실시간 확인하고, 디버그 로그를 추가하며, 스칼라와 벡터를 화면에서 즉시 시각화할 수 있음. 조정이 끝나 프로덕션 빌드가 준비되면 트랜스파일 명령을 실행함.
  • 이 방식은 사람과 봇 모두에게 코드를 읽고 편집하고 프로토타이핑하기 쉬움.

입자 규모와 GPU 연산

  • 엔진 업그레이드를 거쳐 M4 MacBook Air 개발 장비에서 무거운 결합과 연성체 SDF 충돌을 포함한 조건으로 입자 수 한도가 4,000개에서 100,000개로 늘어남.
  • 데이터 처리 방식과 CPU 캐시, SIMD 덕분에 AMD 하드웨어에서도 엔진이 더 원활하게 실행됨.
  • 더 큰 캐시와 높은 클럭을 갖춘 새 Zen 6 칩에서는 수백만 개 입자까지 가능할 수도 있지만, 아직 시험하지 않음.
  • GPU로 연산을 옮기지 않은 이유는 비용이 많이 들고 필요도 없기 때문임. 연간 65달러 서버에서 10,000개 단위 시뮬레이션을 편안하게 실행할 수 있으며 규모 확장도 원활함.