Wat is Geheugenbarrière (memory barrier)?

Instructie die garandeert dat geheugenbewerkingen vóór de barrière eerder voor andere cores zichtbaar zijn dan bewerkingen erna. Ook fence genoemd, zoals fence in RISC-V.

Japanse benaming: メモリバリア

“Geheugenbarrière (memory barrier)” komt voor in 2 oefenvragen uit 1 onderwerpen, bijv. Multicore en synchronisatie.

Vakgebied: Multicore en synchronisatie

Wat een geheugenbarrière garandeert

Een geheugenbarrière (memory barrier), ook fence genoemd, is een instructie die de geheugenbewerkingen van een thread opsplitst in bewerkingen ervóór en erna, en garandeert dat de eerdere zichtbaar worden voor andere cores voordat de latere worden uitgevoerd. Zonder barrière kan een processor loads en stores naar verschillende adressen buiten volgorde laten voltooien, bijvoorbeeld door stores in een store buffer te houden terwijl latere loads doorgaan. Resultaten die de uitvoerende thread zelf ziet, veranderen nooit, dus barrières zijn alleen van belang als data wordt gedeeld tussen cores of met apparaten zoals DMA-engines.

Het store-buffervoorbeeld

Stel dat core 0 x = 1 en daarna r1 = y uitvoert, terwijl core 1 y = 1 en daarna r2 = x uitvoert, met x en y beginnend op 0. Bij sequentiële consistentie gebeurt één store eerst, dus minstens één load moet 1 opleveren. Op echte processors, ook x86, kan elke store in de store buffer van zijn core wachten terwijl de volgende load de oude waarde uit de cache leest, zodat zowel r1 als r2 0 kunnen zijn. Een volledige barrière tussen de store en de load in elke thread dwingt de store zichtbaar te worden voordat de load wordt uitgevoerd, wat die uitkomst uitsluit.

Barrière-instructies in echte ISA's

RISC-V biedt fence, waarvan de operanden aangeven welke eerdere toegangen vóór welke latere moeten worden geordend, zodat fence rw, rw alle lees- en schrijfacties ordent; daarnaast hebben de atomaire en load-reserved/store-conditional-instructies acquire- en release-bits. Arm heeft dmb (data memory barrier) voor ordening, dsb als op voltooiing moet worden gewacht, en load-acquire- en store-release-instructies. Op x86, waarvan total store order (TSO) de meeste ordeningen al behoudt, is mfence of een instructie met lock-prefix vooral nodig om een store vóór een latere load te ordenen. Barrières zijn niet gratis, omdat ze de core kunnen laten stilstaan tot openstaande stores zijn weggeschreven.

Barrières in locks en compilers

De meeste programmeurs schrijven nooit rechtstreeks een barrière. Het verkrijgen van een lock heeft acquire-semantiek, zodat latere toegangen er niet vóór kunnen schuiven, en het vrijgeven heeft release-semantiek, zodat eerdere schrijfacties zichtbaar zijn voordat de lock vrijkomt; daarom gaat data die door een lock wordt beschermd correct van thread naar thread. Programmeertalen bieden dezelfde ideeën aan via atomics met memory orders, zoals in C11 en C++11. Een compilerbarrière is iets anders: die voorkomt alleen dat de compiler toegangen over een bepaald punt heen herordent, maar genereert geen instructie en legt de hardware dus niets op.

Nu oefenen: vragen over Geheugenbarrière (memory barrier)

Wat is de juiste rol van een geheugenbarrière-instructie (fence)?

  1. AGaranderen dat geheugenbewerkingen vóór de barrière voor andere cores eerder zichtbaar zijn dan bewerkingen na de barrière
  2. BHet geheugen fysiek afbakenen en toegang verbieden
  3. CDe uitvoering van het programma stoppen tot alle threads gelijk zijn
Antwoord en toelichting tonen

Antwoord: A. Garanderen dat geheugenbewerkingen vóór de barrière voor andere cores eerder zichtbaar zijn dan bewerkingen na de barrière

Omdat de CPU de volgorde van geheugenbewerkingen kan wijzigen, is voor het in een vaste volgorde uitwisselen van gegevens met andere cores een instructie nodig die dat tegenhoudt. Een geheugenbarrière laat eerst alle voorgaande lees- en schrijfacties voltooien (zichtbaar maken voor andere cores) en pas daarna de volgende uitvoeren. Ook in het nemen en vrijgeven van locks zit het effect van barrières, zodat met een lock beschermde variabelen correct worden doorgegeven.

Veelgestelde vragen

Wat is het verschil tussen een geheugenbarrière en een fence?

Het is hetzelfde concept onder twee namen. Beide verwijzen naar een instructie die ervoor zorgt dat geheugenbewerkingen ervóór, zoals waargenomen door andere cores, geordend blijven vóór de bewerkingen erna; RISC-V noemt zijn instructie fence en Arm noemt zijn instructies barriers.

Heeft x86 geheugenbarrières nodig?

Minder vaak dan zwak geordende architecturen, omdat x86-total store order de meeste loads en stores in programmavolgorde houdt. Een barrière zoals mfence, of een instructie met lock-prefix, is nog steeds nodig als een store zichtbaar moet worden vóór een latere load naar een ander adres.

Wat is het verschil tussen een compilerbarrière en een geheugenbarrière?

Een compilerbarrière voorkomt alleen dat de compiler geheugentoegangen eroverheen verplaatst en genereert geen machine-instructie. Een geheugenbarrière is een hardware-instructie die beperkt in welke volgorde de processor toegangen zichtbaar maakt voor andere cores.

“Geheugenbarrière (memory barrier)” in de toelichting

Vragen met “Geheugenbarrière (memory barrier)” (2)

  1. Wat is de juiste rol van een geheugenbarrière-instructie (fence)?
  2. De bovenstaande twee threads worden tegelijk op verschillende cores uitgevoerd (er is geen herordening door de compiler). Welke uitkomst treedt niet op bij sequentiële consistentie, maar kan wel optreden bij echte CPU's zoals x86?

Verwante termen

Sequentiële consistentie (sequential consistency) Store buffer ABA-probleem Acquire-release Atomaire instructie Barrièresynchronisatie Compare-and-swap Conditievariabele Data race Deadlock

Naar de woordenlijst