Files
2nd/10_Wiki/Topics/bitECS와_SharedArrayBuffer의_실제_코드_통합.md
T

8.1 KiB

category, tags, title, last_updated
category tags title last_updated
Unified
auto-consolidated
technical-documentation
bitECS와 SharedArrayBuffer를 결합한 멀티스레드 고성능 아키텍처|bitECS와 SharedArrayBuffer를 결합한 멀티스레드 고성능 아키텍처
2026-05-02

bitECS와 SharedArrayBuffer를 결합한 멀티스레드 고성능 아키텍처

📌 Brief Summary

bitECS의 데이터 지향 설계(SoA) 구조와 SharedArrayBuffer의 무복사(Zero-Copy) 메모리 공유 기능을 결합하여, 메인 스레드의 렌더링 블로킹 없이 웹 워커에서 수만 개의 엔티티를 병렬 연산하고 실시간으로 동기화하는 초고성능 웹 게임 엔진 아키텍처입니다.


bitECS의 데이터 지향 컴포넌트(SoA) 구조에 기본 자바스크립트 배열 대신 SharedArrayBuffer 기반의 [[TypedArray|TypedArray]](Float32Array 등)를 매핑하여, 멀티스레드 환경에서 복사 오버헤드 없이 실시간으로 데이터를 읽고 쓰는 구현 방식입니다.

📖 Core Content

1. bitECS의 데이터 지향 설계 (Structure of Arrays, SoA) bitECS는 기존의 객체 지향(AoS) 방식 대신, 컴포넌트 데이터를 Float32Array와 같은 [[TypedArray|TypedArray]] 기반의 연속된 배열 구조(SoA)로 저장하는 ECS(Entity ComponentSystem) 라이브러리입니다. 이 구조는 CPU 캐시 적중률을 극대화하여 수천, 수만 개의 엔티티 상태(예: 위치, 속도)를 밀리초 단위로 연산할 수 있게 합니다.

2. SharedArrayBuffer를 통한 Zero-Copy 메모리 공유 bitECS가 내부적으로 사용하는 TypedArray의 기반 메모리를 SharedArrayBuffer로 할당할 수 있습니다. 생성된 버퍼를 웹 워커(Web Worker)로 전달하면 메인 스레드와 워커 스레드가 완전히 동일한 메모리 주소를 공유하게 됩니다. 이를 통해 매 프레임마다 직렬화 및 역직렬화(postMessage) 오버헤드 없이 스레드 간 데이터 통신이 가능해집니다.

3. 스레드 역할의 엄격한 분리 (단방향 데이터 흐름) 동시성 문제(Data Race)를 해결하기 위해 스레드 간의 읽기/쓰기 역할을 아키텍처 수준에서 분리합니다.

  • 워커 스레드 (Write 전담): 물리 엔진 연산, 충돌 처리, AI 이동 로직 등의 bitECS 시스템(System)이 독립적인 백그라운드 루프(예: 60Hz)에서 실행되며, 공유 버퍼의 데이터를 업데이트합니다.
  • 메인 스레드 (Read 전담): React Three Fiber(R3F)useFrame 렌더링 루프 내에서, 공유 메모리의 bitECS 컴포넌트 값(예: Position.x[eid])을 그대로 읽어와 Three.js 메시(Mesh) 인스턴스 참조(ref)에 반영하여 화면에 렌더링합니다.

4. 렌더링과 시뮬레이션의 디커플링 이점 이 아키텍처를 적용하면 무거운 물리 연산이 React의 가상 DOM 재조정(Reconciliation)이나 메인 스레드를 블로킹하지 않습니다. 또한 매 프레임 객체를 새로 생성하지 않고 배열의 값만 변경하므로, 가비지 컬렉션(GC) 스파이크로 인한 프레임 드랍을 원천적으로 방지할 수 있습니다.


1. 데이터 구조의 기반: TypedArray와 SoA(Structure of Arrays) bitECS는 엔티티의 컴포넌트 데이터를 메모리 상에 연속적으로 배치하기 위해 내부적으로 Float32Array와 같은 타입화된 배열(TypedArray)을 사용합니다. 이러한 SoA 방식은 CPU 캐시 효율을 극대화하여 고성능 연산을 가능하게 합니다.

2. SharedArrayBuffer를 이용한 메모리 공유 연결 일반적인 TypedArray는 단일 스레드 메모리에 종속되지만, 그 기반 메모리를 SharedArrayBuffer로 할당하면 스레드 간 공유가 가능해집니다. bitECS 컴포넌트 객체를 선언할 때, 이 공유 버퍼를 참조하는 뷰(View) 배열을 할당하는 방식으로 두 기술을 연결할 수 있습니다.

3. 실제 통합 코드 예시 제공된 bitECS API 구조에 SharedArrayBuffer 개념을 결합한 실제 연결 예시입니다.

import { createWorld, addEntity, addComponent } from 'bitecs';

// 1. SharedArrayBuffer로 공유 메모리 할당 (예: 10만 개 엔티티용, Float32는 4바이트)
const MAX_ENTITIES = 100000;
const bufferX = new SharedArrayBuffer(MAX_ENTITIES * 4);
const bufferY = new SharedArrayBuffer(MAX_ENTITIES * 4);

// 2. 공유 메모리를 바라보는 TypedArray 뷰 생성
const sharedVelocityX = new Float32Array(bufferX);
const sharedVelocityY = new Float32Array(bufferY);

// 3. bitECS 월드 생성 시 공유 배열을 컴포넌트 데이터로 매핑
const world = createWorld({
  components: {
    Velocity: {
      x: sharedVelocityX,
      y: sharedVelocityY
    }
  },
  time: { delta: 0, elapsed: 0, then: performance.now() }
});

const { Velocity } = world.components;

// 4. 엔티티 생성 및 데이터 쓰기 (이 데이터는 공유 메모리에 직접 기록됨)
const eid = addEntity(world);
addComponent(world, eid, Velocity);

Velocity.x[eid] = 1.23; // 공유 메모리의 0번 인덱스에 데이터 쓰기
Velocity.y[eid] = 1.23;

// 5. 웹 워커로 공유 버퍼 전송 (직렬화 오버헤드 없이 메모리 주소만 공유)
// worker.postMessage({ bufferX, bufferY });

4. 스레드 간 데이터 동기화 원리 위와 같이 구성한 후 bufferX, bufferY를 웹 워커로 전달하면 메인 스레드와 워커 스레드는 완벽하게 동일한 메모리를 공유하게 됩니다. 워커 스레드에서 물리 연산을 통해 배열의 x, y 인덱스 값을 업데이트하면, 메인 스레드는 postMessage로 매번 데이터를 넘겨받을 필요 없이 bitECSVelocity.x[eid]를 통해 즉시 렌더링에 반영할 수 있습니다.

⚖️ Trade-offs & Caveats

  • 과거 데이터와의 충돌: 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
  • 정책 변화: Programming & Language 분야의 자동 자산화 수행.

  • 과거 데이터와의 충돌: 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
  • 정책 변화: Programming & Language 분야의 자동 자산화 수행.

🔗 Knowledge Connections

  • Related Topics: Data-Oriented Design (DOD), Structure of Arrays (SoA), Web Worker 멀티스레딩, React Three Fiber (R3F) 최적화, 메모리 파편화 방지 및 객체 풀링
  • Projects/Contexts: 브라우저 기반 AAA급 멀티스레드 3D 게임, 수만 개의 엔티티가 존재하는 실시간 물리 시뮬레이션
  • Contradictions/Notes: 원시 이진 데이터인 SharedArrayBuffer를 직접 다루는 것은 로우 레벨 개발 지식이 필요해 매우 까다롭습니다. 하지만 bitECS를 프록시 구조로 활용하면, 개발자는 익숙한 자바스크립트 배열이나 객체를 다루는 듯한 편의성을 누리면서도 내부적으로는 C++ 엔진에 필적하는 메모리 공유 성능을 얻을 수 있다는 강력한 장점이 있습니다.

Last updated: 2026-04-14



  • Related Topics: Structure of Arrays (SoA), TypedArray (Float32Array), Web Worker postMessage 통신, 메모리 제로 복사 (Zero-Copy)
  • Projects/Contexts: 멀티스레드 기반 웹 게임 물리 엔진 구현, 초대규모 파티클 및 엔티티 시뮬레이션 (React Three Fiber)
  • Contradictions/Notes: bitECS와 같은 프록시 객체를 사용하면 원시 메모리를 다루는 로우 레벨 프로그래밍을 자바스크립트 객체 배열(JS objects) 다루듯 쉽게 접근할 수 있게 해줍니다. 하지만 이렇게 최적화를 하더라도, 개발자가 일반적으로 즐겨 사용하는 유연한 JSON 구조의 객체 데이터 포맷과는 여전히 거리가 멀고 데이터의 형태가 고정되어야 한다는 설계적 제약이 따릅니다.

Last updated: 2026-04-14