Threading (SharedArrayBuffer) — WebAssembly

Multi-Threading dengan Wasm WebAssembly mendukung shared memory dan threads melalui SharedArrayBuffer dan Web Workers. Ini memungkinkan parallel computation unt

Multi-Threading dengan Wasm

WebAssembly mendukung shared memory dan threads melalui SharedArrayBuffer dan Web Workers. Ini memungkinkan parallel computation untuk workload berat seperti ray tracing, video encoding, atau physics simulation.

Prerequisites

// SharedArrayBuffer butuh Cross-Origin Isolation headers:
// Server harus kirim:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

// Cek di browser:
console.log(crossOriginIsolated); // harus true
console.log(typeof SharedArrayBuffer); // "function"

SharedArrayBuffer Basics

// Buat shared memory (bisa diakses dari multiple workers)
const sharedBuffer = new SharedArrayBuffer(1024); // 1KB shared
const view = new Int32Array(sharedBuffer);

// Main thread
view[0] = 42;

// Kirim ke worker (zero-copy! tidak di-clone)
worker.postMessage({ buffer: sharedBuffer });

// Worker bisa baca/tulis ke memory yang sama
// tanpa overhead serialization/deserialization

Atomics: Thread-Safe Operations

const shared = new SharedArrayBuffer(4);
const view = new Int32Array(shared);

// Thread-safe operations
Atomics.store(view, 0, 100);        // atomic write
const val = Atomics.load(view, 0);   // atomic read: 100

Atomics.add(view, 0, 5);            // atomic add: 105
Atomics.sub(view, 0, 3);            // atomic sub: 102

// Compare and swap (CAS)
Atomics.compareExchange(view, 0, 102, 200);
// Jika view[0] == 102, set ke 200

// Wait / Notify (mutex-like)
// Worker:
Atomics.wait(view, 0, 0);           // block sampai notify

// Main:
Atomics.notify(view, 0, 1);         // bangunkan 1 waiter

Wasm Threads (Rust)

// Cargo.toml
[dependencies]
wasm-bindgen = "0.2"
rayon = "1"
wasm-bindgen-rayon = "1"

// Build flags
// .cargo/config.toml
[target.wasm32-unknown-unknown]
rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals"]
use rayon::prelude::*;
use wasm_bindgen::prelude::*;

// Initialize thread pool
#[wasm_bindgen]
pub fn init_threads(num_threads: usize) -> Result<(), JsValue> {
    wasm_bindgen_rayon::init_thread_pool(num_threads)
}

// Parallel computation
#[wasm_bindgen]
pub fn parallel_sum(data: &[f64]) -> f64 {
    data.par_iter().sum()
}

// Parallel image processing
#[wasm_bindgen]
pub fn parallel_grayscale(pixels: &mut [u8]) {
    pixels.par_chunks_mut(4).for_each(|pixel| {
        let gray = (0.299 * pixel[0] as f32
                  + 0.587 * pixel[1] as f32
                  + 0.114 * pixel[2] as f32) as u8;
        pixel[0] = gray;
        pixel[1] = gray;
        pixel[2] = gray;
    });
}

Tips

Yang akan kamu pelajari