WebAssembly (WASM) voor performante toepassingen · Les

SharedArrayBuffer en atomics voor WASM

Gebruik SharedArrayBuffer en atomaire bewerkingen voor efficiënte, gesynchroniseerde gegevenstoegang tussen meerdere WASM-threads.

Les 2 van 412 stappen

SharedArrayBuffer en atomics voor WASM is een gratis WebAssembly (WASM) voor performante toepassingen-les op CoddyKit. Dit is les 2 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject WebAssembly (WASM) voor performante toepassingen. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus WebAssembly (WASM) voor performante toepassingen bevat in totaal 4 lessen.

Gegevens veilig delen in WASM

Bij het bouwen van applicaties met hoge prestaties met WebAssembly (WASM) moet je vaak gegevens delen tussen verschillende onderdelen van je programma, vooral tussen meerdere threads (Web Workers).

Geheugen rechtstreeks delen kan problemen veroorzaken, zoals racecondities, waarbij meerdere threads tegelijkertijd dezelfde gegevens proberen te lezen en te wijzigen, met onvoorspelbare resultaten als gevolg.

In deze les maak je kennis met SharedArrayBuffer en atomaire bewerkingen, essentiële hulpmiddelen voor het veilig en efficiënt delen van gegevens in WASM-applicaties met meerdere threads.

Wat is SharedArrayBuffer?

Een SharedArrayBuffer is een speciaal type gegevensbuffer in JavaScript dat kan worden gedeeld tussen de hoofdthread en Web Workers.

  • In tegenstelling tot een gewone ArrayBuffer, die alleen naar een worker kan worden overgedragen (gekopieerd), biedt een SharedArrayBuffer een gedeelde geheugenruimte.
  • Dit betekent dat alle threads die er toegang toe hebben dezelfde gegevens tegelijkertijd zien, zonder dat deze heen en weer moeten worden gekopieerd.
  • Het vormt de basis voor echte multithreading met WASM in webomgevingen.

JS: gedeeld geheugen toewijzen

Je maakt aan de JavaScript-kant een SharedArrayBuffer, net als een gewone ArrayBuffer, maar met de constructor SharedArrayBuffer.

Na het maken kun je weergaven van getypeerde arrays maken (bijvoorbeeld Uint32Array) om gegevens te lezen en te schrijven. Deze buffer kan vervolgens worden doorgegeven aan Web Workers.

Zo kun je er een instellen in JavaScript:

// In JavaScript:
const sharedBuffer = new SharedArrayBuffer(1024); // 1KB shared memory
const view = new Uint32Array(sharedBuffer); // A view to work with

// Now, 'sharedBuffer' can be passed to Web Workers
// worker.postMessage({ sharedBuffer });

WASM-modules die in deze workers zijn geladen, kunnen vervolgens toegang krijgen tot dit gedeelde geheugen.

De kijk op gedeeld geheugen van WASM

Wanneer een SharedArrayBuffer aan een Web Worker wordt doorgegeven en een WebAssembly-module wordt geïnstantieerd met een WebAssembly.Memory-object dat deze gedeelde buffer gebruikt, krijgt de WASM-module rechtstreeks toegang tot die buffer.

  • WASM ziet dit gedeelde geheugen als zijn eigen lineaire geheugen.
  • Alle lees- en schrijfbewerkingen van de WASM-module in zijn lineaire geheugen worden rechtstreeks weerspiegeld in de SharedArrayBuffer.
  • Hierdoor kunnen WASM-instanties die in verschillende workers worden uitgevoerd in realtime met exact dezelfde gegevens werken.

Het probleem: racecondities

Stel je twee Web Workers voor die elk een WASM-module uitvoeren en een gedeelde teller in een SharedArrayBuffer proberen te verhogen.

Als beide workers de huidige waarde lezen, deze verhogen en vervolgens zonder coördinatie terugschrijven, kan er een raceconditie ontstaan:

  • Worker A leest 0.
  • Worker B leest 0.
  • Worker A verhoogt 0 naar 1 en schrijft 1.
  • Worker B verhoogt 0 naar 1 en schrijft 1.

De teller zou 2 moeten zijn, maar eindigt als 1! Hier worden atomaire bewerkingen cruciaal.

Atomaire bewerkingen schieten te hulp!

Atomaire bewerkingen zijn speciale instructies die garanderen dat een bewerking volledig wordt uitgevoerd zonder onderbreking door andere threads.

Ze zijn "alles of niets": de volledige bewerking wordt succesvol voltooid of gebeurt helemaal niet. Zo worden gedeeltelijke updates en racecondities voorkomen.

Belangrijke kenmerken:

  • Ondeelbaar: Kan niet worden onderbroken door een andere thread.
  • Gegarandeerd: Waarborgt de integriteit van gegevens bij gelijktijdige toegang.
  • Essentieel: Voor het bouwen van betrouwbare applicaties met meerdere threads.

Rust: atomaire verhoging voor WASM

Rust biedt atomaire typen (zoals AtomicU32 en AtomicI64) in zijn module std::sync::atomic. Deze kunnen worden gebruikt wanneer je naar WebAssembly compileert.

Wanneer deze bewerkingen naar WASM worden gecompileerd, worden ze vertaald naar de onderliggende atomaire WebAssembly-instructies, die veilig werken op gedeeld lineair geheugen.

Hier volgt een eenvoudig Rust-voorbeeld met een atomaire teller die onderdeel kan zijn van een WASM-module:

use std::sync::atomic::{AtomicU32, Ordering};

// A static atomic counter within the WASM module.
// In a full shared memory setup, this would conceptually map
// to an offset within the SharedArrayBuffer passed from JS.
static GLOBAL_COUNTER: AtomicU32 = AtomicU32::new(0);

#[no_mangle]
pub extern "C" fn increment_counter_atomic(amount: u32) -> u32 {
    // Atomically add 'amount' to GLOBAL_COUNTER.
    // Ordering::SeqCst ensures sequential consistency.
    GLOBAL_COUNTER.fetch_add(amount, Ordering::SeqCst);
    // Return the new value (after incrementing)
    GLOBAL_COUNTER.load(Ordering::SeqCst)
}

#[no_mangle]
pub extern "C" fn get_current_counter_atomic() -> u32 {
    // Atomically load the current value.
    GLOBAL_COUNTER.load(Ordering::SeqCst)
}

JS: het Atomics-object

JavaScript heeft ook een eigen Atomics-object. Dit biedt statische methoden om rechtstreeks atomaire bewerkingen uit te voeren op weergaven van SharedArrayBuffer.

Hiermee kunnen de hoofdthread van JavaScript of Web Workers atomaire bewerkingen uitvoeren op het gedeelde geheugen en zo samenwerken met WASM-modules.

  • Atomics.add(view, index, value): Voegt value atomair toe aan het element op index in view.
  • Atomics.load(view, index): Laadt atomair de waarde op index.
  • Atomics.store(view, index, value): Slaat value atomair op op index.

Deze methoden zijn cruciaal om vanuit JavaScript veilig te communiceren met het gedeelde geheugen van WASM.

Synchronisatie met Wait/Notify

Naast eenvoudige lees- en schrijfbewerkingen biedt Atomics ook methoden voor geavanceerdere threadsynchronisatie:

  • Atomics.wait(view, index, expectedValue, timeout): Hiermee kan een thread slapen (blokkeren) totdat een specifieke geheugenlocatie (view[index]) niet langer expectedValue bevat, of totdat er een time-out optreedt.
  • Atomics.notify(view, index, count): Hiermee worden een of meer threads gewekt die op de opgegeven geheugenlocatie wachten.

Dit zijn krachtige hulpmiddelen voor het bouwen van complexe patronen met meerdere threads, zoals producent-consumentwachtrijen, waarbij threads moeten pauzeren en hervatten op basis van wijzigingen in gedeelde gegevens.

Een gelijktijdige teller bouwen

Door SharedArrayBuffer en atomische bewerkingen te combineren, kun je robuuste gelijktijdige toepassingen bouwen. Bijvoorbeeld een gedeelde teller:

  • JavaScript: Maakt een SharedArrayBuffer en een weergave van het type Uint32Array.
  • Web Workers: Elke worker ontvangt de SharedArrayBuffer en maakt een WASM-module-instantie.
  • WASM-module: De WASM-code (zoals in ons Rust-voorbeeld) gebruikt atomische bewerkingen om een specifieke index in het lineaire geheugen te verhogen. Dit geheugen wordt ondersteund door de SharedArrayBuffer.

Deze opzet zorgt ervoor dat de uiteindelijke waarde altijd correct is, zelfs wanneer meerdere threads de teller snel verhogen, en voorkomt racecondities.

Controleer je begrip

Wat zijn de belangrijkste voordelen van het gebruik van SharedArrayBuffer en atomische bewerkingen in WebAssembly?

Samenvatting: gedeeld geheugen en atomische bewerkingen

We hebben onderzocht hoe SharedArrayBuffer echt gedeeld geheugen tussen JavaScript-threads en WebAssembly-modules mogelijk maakt. Daarmee wordt de weg vrijgemaakt voor WASM-toepassingen met meerdere threads.

We hebben vooral geleerd dat atomische bewerkingen onmisbaar zijn om dit gedeelde geheugen veilig te beheren. Ze voorkomen racecondities en zorgen voor consistente gegevens wanneer meerdere threads dezelfde gegevens gelijktijdig benaderen en wijzigen.

Beheersing van deze concepten is essentieel voor het bouwen van snelle, betrouwbare WebAssembly-toepassingen die optimaal gebruikmaken van moderne processors met meerdere kernen.

Gratis beginnen

Leer WebAssembly (WASM) voor performante toepassingen met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
12
Lessen
48

Veelgestelde vragen

Is de les “SharedArrayBuffer en atomics voor WASM” gratis?

Ja — de volledige tekst van “SharedArrayBuffer en atomics voor WASM” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus WebAssembly (WASM) voor performante toepassingen wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus WebAssembly (WASM) voor performante toepassingen bevat in totaal 4 lessen.

Wat leer ik in “SharedArrayBuffer en atomics voor WASM”?

Gebruik SharedArrayBuffer en atomaire bewerkingen voor efficiënte, gesynchroniseerde gegevenstoegang tussen meerdere WASM-threads. Je oefent met WebAssembly (WASM) voor performante toepassingen door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met WebAssembly (WASM) voor performante toepassingen te beginnen?

Ervaring vooraf is niet nodig. WebAssembly (WASM) voor performante toepassingen op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 2 van 4.

Hoe lang duurt de les “SharedArrayBuffer en atomics voor WASM”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over WebAssembly (WASM) voor performante toepassingen?

Ja. Elke les over WebAssembly (WASM) voor performante toepassingen bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Web Workers met WASM-threads
  2. SharedArrayBuffer en atomics voor WASM
  3. Gelijktijdige WASM-applicaties ontwerpen
  4. Berichtenuitwisseling en kanalen tussen WASM-threads
← Terug naar WebAssembly (WASM) voor performante toepassingen