90 lines
8.6 KiB
Markdown
90 lines
8.6 KiB
Markdown
---
|
|
category: Unified
|
|
tags: [auto-consolidated, technical-documentation]
|
|
title: [[SharedArrayBuffer 동시성 문제 해결법|SharedArrayBuffer 동시성 문제 해결법]]
|
|
last_updated: 2026-05-02
|
|
---
|
|
|
|
# [[SharedArrayBuffer 동시성 문제 해결법|SharedArrayBuffer 동시성 문제 해결법]]
|
|
|
|
## 📌 Brief Summary
|
|
> `SharedArrayBuffer`는 여러 스레드가 동일한 메모리 영역을 동시에 공유하기 때문에 데이터 경쟁 상태(Data Race)가 발생할 수 있으며, 이를 해결하기 위해 **원자적 연산(Atomic [[Opera|Opera]]tions)** 지원을 활용하거나 **아키텍처 설계(ECS 등)**를 통해 스레드 간의 읽기/쓰기 역할을 명확히 분리해야 합니다.
|
|
|
|
---
|
|
|
|
> SharedArrayBuffer는 다중 스레드 환경에서 Web Worker와 메인 스레드 간에 데이터를 공유할 때 메모리 과부하를 방지하기 위해 사용되는 기술입니다 [1]. 전통적인 데이터 전달 방식과 달리 메모리를 복제하지 않는 제로 카피(Zero-copy) 아키텍처를 구현할 수 있게 해줍니다 [1]. 이를 통해 Electron과 같은 환경에서 대규모 3D 모델을 로드하고 파싱할 때 메모리 안정성을 획기적으로 유지할 수 있습니다 [1, 2].
|
|
|
|
---
|
|
|
|
> **SharedArrayBuffer**는 웹 워커(Web Worker)와 메인 스레드 간의 전통적인 통신 방식인 `postMessage`의 데이터 직렬화(Serialization) 및 복사 오버헤드를 제거하고, **두 스레드가 동일한 메모리 영역을 복사 없이(Zero-copy) 직접 접근하고 공유**할 수 있게 해주는 저수준(Low-level)의 고성능 최적화 기법입니다.
|
|
|
|
## 📖 Core Content
|
|
**1. 원자적 연산 (Atomic Operations) 활용** `SharedArrayBuffer`는 메인 스레드와 워커 스레드 등 서로 다른 컨텍스트에서 데이터를 복사 없이 공유할 수 있도록 지원하며, 동시 접근으로 인한 충돌을 막기 위해 원자적 연산(Atomic operations)을 지원합니다. _(※ 외부 지식 참고: 자바스크립트에서는 이를 위해 내장된 `Atomics` 전역 객체를 사용합니다. `Atomics.load()`, `Atomics.store()`, `Atomics.add()`, `Atomics.compareExchange()` 등의 API를 사용하면 특정 메모리 주소에 대한 읽기와 쓰기가 중간에 끊기지 않는 '단일 연산'으로 보장되어 안전하게 데이터를 제어할 수 있습니다.)_
|
|
|
|
**2. 스레드 동기화 제어 (Lock / Wait 메커니즘)** _(※ 외부 지식 참고: 동시성 충돌을 더욱 엄격하게 제어해야 할 경우 `Atomics.wait()`와 `Atomics.notify()`를 활용해 특정 스레드를 대기 상태로 만들고 작업이 끝난 후 깨우는 방식(Lock, Mutex 패턴)을 구현하여 다중 스레드의 접근 순서를 동기화할 수 있습니다.)_
|
|
|
|
**3. 아키텍처적 해결: ECS(Entity ComponentSystem)를 통한 읽기/쓰기 역할 분리** 가장 효율적인 방식은 엔진 구조 자체에서 데이터의 단방향 흐름을 강제하여 충돌을 회피하는 것입니다. 고성능 게임 엔진 아키텍처에서는 ECS의 컴포넌트 데이터를 `SharedArrayBuffer`에 할당한 후, 스레드의 역할을 엄격하게 분리합니다.
|
|
|
|
- **쓰기(Write) 전담 스레드:** 웹 워커(Web Worker)는 백그라운드에서 물리 연산이나 AI 로직 등을 수행하며 버퍼의 데이터를 업데이트(Write)합니다.
|
|
- **읽기(Read) 전담 스레드:** 메인 스레드(React 및 렌더링 루프)는 렌더링 시점에 버퍼에서 데이터를 즉시 읽어와(Read) 복사 비용 없이 [[WebGL|WebGL]]/Three.js 메시의 속성에 반영합니다. 이러한 데이터 지향 설계(Data-Oriented Design)를 채택하면 여러 스레드가 동일한 데이터에 동시에 쓰기 작업을 하는 상황을 구조적으로 방지할 수 있습니다.
|
|
|
|
---
|
|
|
|
본문 구조화 작업 중...
|
|
|
|
---
|
|
|
|
**1. 직렬화(Serialization) 병목 제거** 자바스크립트 환경에서 메인 스레드와 워커 스레드는 기본적으로 메모리를 공유하지 않기 때문에, 데이터를 주고받으려면 내부적으로 데이터를 복사하고 직렬화/역직렬화하는 과정을 거쳐야 합니다. 그러나 `SharedArrayBuffer`를 사용하면 이러한 복사 과정 없이 데이터가 포함된 원시 바이너리 버퍼 자체를 공유하므로, 메모리 전송에 소모되는 지연 시간(오버헤드)이 '0'에 가까워집니다.
|
|
|
|
**2. ECS(Entity ComponentSystem) 기반 아키텍처와의 시너지** 이 기술은 `bitECS`와 같은 고성능 게임 아키텍처 패턴(ECS)과 결합할 때 진가를 발휘합니다. 게임 내 수만 개의 엔티티(파티클, 총알, 적 등) 정보를 무거운 자바스크립트 객체 대신 연속된 메모리 블록인 `[[TypedArray|TypedArray]]` 구조로 구성한 뒤, 이를 `SharedArrayBuffer`에 적재합니다.
|
|
|
|
- **워커 스레드(물리 엔진/AI):** 물리 연산을 수행하여 버퍼 내의 좌표($x, y, z$) 데이터를 업데이트합니다.
|
|
- **메인 스레드(React/Three.js):** 메시지 수신을 기다릴 필요 없이, 버퍼의 메모리 주소를 즉시 읽어와 `[[InstancedMesh|InstancedMesh]]` 등을 60FPS로 렌더링합니다.
|
|
|
|
**3. Atomics API를 통한 원자적(Atomic) 동기화 보장** 여러 스레드가 동시에 동일한 메모리 공간에 읽기/쓰기를 수행하면 데이터가 꼬이는 경쟁 상태(Race Condition)가 발생할 수 있습니다. `SharedArrayBuffer`는 `Atomics` 객체에서 제공하는 원자적 연산을 지원하여, 스레드 간에 안전하게 메모리를 조작하고 동기화할 수 있도록 보장합니다.
|
|
|
|
**4. 한계점 및 개발 트레이드오프 (Trade-offs)**
|
|
|
|
- **매우 낮은 추상화 수준:** 일반적인 JSON 객체나 유연한 자바스크립트 데이터 구조를 사용할 수 없으며, 바이트 단위의 로우 레벨 바이너리 버퍼를 직접 계산하고 다뤄야 하므로 개발 난이도가 매우 높고 사용자 친화적이지 않습니다.
|
|
- **보안 제약 (COOP/COEP):** 멜트다운(Meltdown) 및 스펙터([[Spectre|Spectre]])와 같은 CPU 보안 취약점을 방지하기 위해, 웹 서버에서 보안 헤더(`Cross-Origin-Opener-Policy` 및 `Cross-Origin-Embedder-Policy`)를 엄격하게 설정해야만 브라우저에서 `SharedArrayBuffer` 기능을 활성화할 수 있습니다. (※ 이 내용은 제공된 소스 외부의 일반적인 웹 보안 지식입니다. 실제 도입 시 서버 설정 확인이 필요합니다.)
|
|
|
|
## ⚖️ Trade-offs & Caveats
|
|
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
|
|
- **정책 변화:** Programming & Language 분야의 자동 자산화 수행.
|
|
|
|
---
|
|
|
|
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
|
|
- **정책 변화:** Graphics & Performance 분야의 자동 자산화 수행.
|
|
|
|
---
|
|
|
|
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
|
|
- **정책 변화:** Programming & Language 분야의 자동 자산화 수행.
|
|
|
|
## 🔗 Knowledge Connections
|
|
- **Related Topics:** Web Worker, Atomics API, 경쟁 상태 (Race Condition), Data-Oriented Design (ECS)
|
|
- **Projects/Contexts:** 멀티스레드 React WebGL 애플리케이션, 고성능 실시간 상호작용 시스템
|
|
- **Contradictions/Notes:** `SharedArrayBuffer`는 지연 시간을 극도로 낮추고 복사 비용을 '0'으로 만들지만, 로우 레벨의 이진 데이터 버퍼를 직접 다뤄야 하고 `Atomics`로 동시성을 관리해야 하므로 구현 복잡도가 매우 높습니다 [264, 895, 이전 대화 내용 참조]. 따라서 충돌 제어와 개발 편의성이 더 중요한 일반적인 경우에는 Valtio 등 프록시(Proxy)를 사용해 `BroadcastChannel`이나 `postMessage`로 변경점(Delta)만 동기화하는 메시지 기반 패턴이 더 직관적일 수 있습니다.
|
|
|
|
---
|
|
|
|
_Last updated: 2026-04-14_
|
|
|
|
---
|
|
|
|
---
|
|
|
|
- **Related Topics:** [[Web Worker (웹 워커)|Web Worker]], Structured Cloning, [[BufferAttribute|BufferAttribute]], Zero-copy architecture
|
|
- **Projects/Contexts:** Electron 기반 WebGL CAD 렌더링 최적화
|
|
- **Contradictions/Notes:** 소스에서는 워커를 활용할 때 기존의 Structured Cloning을 사용할 경우 데이터가 전체 복사되어 OOM이 발생할 위험이 크지만, SharedArrayBuffer를 사용하면 복사 과정을 없애(Zero-copy) 이러한 메모리 오버헤드를 완벽히 방지할 수 있다고 대조하여 설명합니다 [1].
|
|
|
|
---
|
|
*Last updated: 2026-04-19*
|
|
- Raw Source: 00_Raw/2026-04-20/SharedArrayBuffer.md
|
|
---
|
|
|
|
---
|
|
|
|
---
|