Belajar WebAssembly - Multithreading, WASM & JIT/GC
Episode 21 of 23

Belajar WebAssembly - Multithreading, WASM & JIT/GC

Menguasai komputasi paralel dan runtime modern: SharedArrayBuffer dan proposal threads, web-workers dan pthreads di Emscripten, WasmGC dengan wasi-threads, JIT tiering di V8/SpiderMonkey, serta dukungan bahasa GC seperti C# .NET 10 dan Kotlin/Wasm

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 20 kalian melihat roadmap WASI menuju 1.0 — pada episode ini kita membahas dua kemampuan yang menjadi pembeda antara "Wasm sebagai eksperimen" dan "Wasm sebagai platform komputasi serius": multithreading dan runtime modern (JIT/GC). Keduanya adalah batas terakhir yang harus dilewati Wasm agar benar-benar setara dengan native.

Mengapa topik ini penting? Karena workload dunia nyata jarang single-thread. Image processing, machine learning, analitik — semuanya butuh paralelisme. Dan dukungan GC membuka Wasm untuk bahasa yang dikelola memory otomatis (C#, Kotlin, Java, Python), yang selama ini hanya bisa dijalankan dengan runtime raksasa.

Threads di Browser: SharedArrayBuffer

Model threading browser berbasis Web Workers + SharedArrayBuffer. Beberapa worker berbagi satu blok memory; Wasm pada masing-masing worker bisa mengaksesnya secara paralel.

JSshared-worker.js
// main thread
const sab = new SharedArrayBuffer(1024)
const worker = new Worker("worker.js")
 
// worker.js
onmessage = () => {
  const view = new Int32Array(sab)
  const hasil = instance.exports.hitung(0, view.length) // modul wasm mengisi buffer
  postMessage({ hasil })
}

Penting untuk dipahami: SharedArrayBuffer membutuhkan cross-origin isolation (COOP/COEP headers) — browser mewajibkannya demi keamanan:

Cross-Origin Isolation
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

Tanpa kedua header ini, SharedArrayBuffer tidak tersedia di browser utama.

Threads Proposal dan atomics

Wasm menambahkan instruksi atomics yang bekerja di atas memory bersama:

  • i32.atomic.load/store — operasi atomik.
  • i32.atomic.rmw.* — read-modify-write atomik (fetch-add, compare-exchange).
  • memory.atomic.wait / notify — sinkronisasi antar thread.
atomic-counter.wat
(module
  (memory 1 1 shared)              ;; memory shared untuk lintas thread
  (func $tambah (param $amt i32)
    (i32.atomic.rmw.add (i32.const 0) (local.get $amt))
    drop
  )
  (export "tambah" (func $tambah))
)

Dengan atomics, counter bersama aman diperbarui oleh banyak worker tanpa race condition.

pthreads di Emscripten

Untuk C/C++, Emscripten menyediakan pthreads — implementasi POSIX threads di atas Web Workers. Kode yang memakai pthread_create bisa dikompilasi hampir tanpa perubahan:

Compile dengan pthreads
emcc -O3 -pthread -s PTHREAD_POOL_SIZE=4 parallel.c -o parallel.js

Emscripten membuat satu Web Worker per thread, berbagi memory via SharedArrayBuffer, dan menyediakan mutex/condvar. Hasilnya: kode C multithread berjalan di browser dengan sedikit modifikasi.

Tip

Aturan praktis untuk browser: jangan buat thread sebanyak core secara naif. Di Web Workers, biaya spawn dan sinkronisasi tinggi — mulai dengan jumlah thread kecil (2-4) dan ukur. Sering kali paralelisme kasar (memecah data per worker) lebih menang daripada lock halus.

wasi-threads di Server

Di sisi server, wasi-threads membawa model threads ke WASI. Dengan WASI 0.3.x (episode 20), threads menjadi bagian dari roadmap resmi — komputasi paralel lintas core dengan model yang aman dan terkontrol.

Jalankan dengan thread pool di Wasmtime
wasmtime run --pool-max-threads=8 parallel.wasm

Dampaknya: workload yang selama ini terbatas satu thread di Wasm — encoding, hashing, parsing besar — kini bisa memanfaatkan seluruh core mesin, bersaing langsung dengan binary native.

JIT Tiering: V8 dan SpiderMonkey

Engine browser mengkompilasi Wasm berlapis. Pola umum tiering:

  1. Baseline compiler — kompilasi cepat, eksekusi bisa dimulai dalam milidetik.
  2. Optimizing compiler — fungsi "panas" (sering dipanggil) dikompilasi ulang dengan optimasi agresif.
  3. (Opsional) AOT di beberapa runtime server — dikompilasi saat deploy, bukan saat runtime.
100%

Implikasi praktisnya (kembali ke episode 13 dan 15): jangan benchmark sebelum warm-up, dan jangan heran jika run pertama jauh lebih lambat dari run kesepuluh.

WasmGC: Bahasa Ber-GC di Wasm

WasmGC (episode 9) kini menjadi kenyataan praktis:

C# .NET 10

.NET 10 bisa mengkompilasi ke Wasm dengan runtime yang lebih kecil — GC disediakan engine, bukan runtime .NET:

C#hello-dotnet-wasm.cs
public static class Program
{
    public static string Sapaan(string nama) => $"Halo, {nama}!";
}

Konsekuensinya besar: aplikasi .NET bisa berjalan di browser/edge dengan startup yang jauh lebih ringan.

Kotlin/Wasm (Beta)

Kotlin/Wasm memungkinkan kode Kotlin — termasuk yang memakai standard library dan coroutine — berjalan langsung di Wasm tanpa JavaScript interop layer:

Kotlinhello-kotlin.kt
fun hitungFibonacci(n: Int): Int = when {
    n < 2 -> n
    else -> hitungFibonacci(n - 1) + hitungFibonacci(n - 2)
}

Safari: Interpreter Start

Safari mengambil pendekatan berbeda di sebagian jalur: memakai interpreter untuk start cepat sebelum naik ke JIT. Konsekuensinya: Safari bisa jadi lambat di benchmark awal, tapi stabil dan hemat memory — sangat relevan jika pengguna kalian banyak di ekosistem Apple.

Note

Tiga kategori bahasa sekarang bisa masuk Wasm: bahasa tanpa GC (Rust/C/C++ — jalur mapan), bahasa ber-GC (C#/Kotlin/Java/Python — jalur WasmGC), dan JavaScript sendiri (lewat JS engine seperti QuickJS/JerryScript yang dikompilasi ke Wasm). Pilihan toolchain menentukan seberapa besar runtime yang ikut serta.

Common Pitfalls

  • SharedArrayBuffer tanpa COOP/COEP — fitur tidak tersedia; aktifkan cross-origin isolation sejak awal.
  • Race condition di memory bersama — atomics wajib untuk counter/shared flags; jangan mengandalkan urutan eksekusi worker.
  • Threads di browser terbatas — worker tidak selalu menang; ukur overhead spawn vs speedup.
  • WasmGC masih muda — bahasa ber-GC di Wasm belum matang untuk semua workload; uji ekosistem tooling-nya.
  • Benchmark tanpa warm-up — tiering membuat angka pertama menyesatkan.

Penutup

Pada episode 21 ini, kalian telah memahami multithreading dan runtime modern di ekosistem WebAssembly.

Inti yang harus dibawa pulang:

  • Threads di browser = Web Workers + SharedArrayBuffer + atomics; butuh cross-origin isolation.
  • Emscripten pthreads mem-port kode C/C++ multithread dengan perubahan minimal.
  • wasi-threads membawa paralelisme ke server dengan model terkontrol.
  • JIT tiering (baseline → optimizing) berarti benchmark harus setelah warm-up.
  • WasmGC membuka Wasm untuk C# .NET 10 dan Kotlin/Wasm; Safari memakai interpreter untuk start cepat.

Di episode 22 selanjutnya, episode penutup series, kita akan membandingkan WebAssembly dengan alternatifnya — Java/JVM, Native, JavaScript, dan Docker container — menentukan kapan memilih masing-masing, rekap lengkap episode 0-21, serta checklist production dan sumber belajar resmi. Sampai jumpa di episode 22!

Belajar WebAssembly - Multithreading, WASM & JIT/GC | Belajar Web Assembly