29 メモリーモデル (Memory Model)

メモリ一貫性モデル、すなわち memory model は、SharedArrayBuffer に裏付けられた TypedArray インスタンスへのアクセスおよび Atomics オブジェクト上のメソッドにより生じる Shared Data Block イベントの起こり得る順序を規定する。プログラムに(後述の定義による)データ競合がない場合、イベント順序は逐次的一貫性 (sequentially consistent) として現れ、すなわち各エージェントのアクションのインターリーブとして現れる。プログラムにデータ競合がある場合、共有メモリアクセスは逐次的一貫性を欠いて見える可能性がある。例えばプログラムは因果律に反する振る舞いやその他の驚きを示し得る。これらの驚きはコンパイラ変換および CPU 設計(例: 命令のアウトオブオーダ実行や投機)に由来する。メモリーモデルはプログラムが逐次的一貫性を示す正確な条件と、データ競合から読み得る値の可能性を定義する。言い換えると、undefined behaviour は存在しない。

メモリーモデルは SharedArrayBuffer 上の抽象操作または Atomics オブジェクト上のメソッドによって評価中に導入されるイベントに対する関係制約として定義される。

Note

この節は SharedArrayBuffer 上の抽象操作によって導入されるイベントに関する公理的モデルを提供する。モデルは仕様の他の部分と異なりアルゴリズム的に表現できないことを強調する。抽象操作によるイベントの非決定的導入は ECMAScript 評価の操作的意味論とメモリーモデルの公理的意味論とのインタフェースである。これらイベントの意味は評価内の全イベントのグラフを考慮して定義される。これらは静的意味論でも実行時意味論でもない。既知のアルゴリズム実装は示されておらず、代わりに特定のイベントグラフが許容されるか否かを決定する制約集合がある。

29.1 メモリーモデルの基本 (Memory Model Fundamentals)

共有メモリアクセス(読み書き)は後述の定義に従い atomic アクセスと data アクセスの 2 群に分けられる。Atomic アクセスは逐次的一貫性を持つ、すなわちエージェントクラスタ内の全エージェントが合意する厳密な全順序が存在する。非 atomic アクセスは全エージェントが合意する厳密な全順序を持たず、すなわち unordered である。

Note 1

逐次的一貫性より弱く、unordered より強い順序(例: release-acquire)はサポートされない。

Shared Data Block eventReadSharedMemoryWriteSharedMemory、または ReadModifyWriteSharedMemory Record のいずれかである。

Table 94: ReadSharedMemory イベントフィールド (ReadSharedMemory Event Fields)
Field Name Value Meaning
[[Order]] seq-cst または unordered このイベントに対してメモリーモデルが保証する最弱の順序。
[[NoTear]] Boolean このイベントが同一範囲を持つ複数の書き込みイベントから読み取ることを許されるかどうか。
[[Block]] Shared Data Block イベントが作用するブロック。
[[ByteIndex]] 非負整数 [[Block]] 内での読み取りのバイト位置。
[[ElementSize]] 非負整数 読み取りサイズ。
Table 95: WriteSharedMemory イベントフィールド (WriteSharedMemory Event Fields)
Field Name Value Meaning
[[Order]] seq-cst, unordered, または init このイベントに対してメモリーモデルが保証する最弱の順序。
[[NoTear]] Boolean このイベントが同一範囲を持つ複数の読み取りイベントから読み取られることを許されるかどうか。
[[Block]] Shared Data Block イベントが作用するブロック。
[[ByteIndex]] 非負整数 [[Block]] 内での書き込みのバイト位置。
[[ElementSize]] 非負整数 書き込みサイズ。
[[Payload]] バイト値List 他のイベントによって読み取られるバイト値List
Table 96: ReadModifyWriteSharedMemory イベントフィールド (ReadModifyWriteSharedMemory Event Fields)
Field Name Value Meaning
[[Order]] seq-cst Read-modify-write イベントは常に逐次的一貫性。
[[NoTear]] true Read-modify-write イベントは tear しない。
[[Block]] Shared Data Block イベントが作用するブロック。
[[ByteIndex]] 非負整数 [[Block]] 内での read-modify-write のバイト位置。
[[ElementSize]] 非負整数 read-modify-write のサイズ。
[[Payload]] バイト値List [[ModifyOp]] に渡されるバイト値List
[[ModifyOp]] read-modify-write 変更関数 読み取ったバイト値List[[Payload]] から変更後のバイト値List を返す抽象クロージャ。

これらのイベントは抽象操作または Atomics オブジェクト上のメソッドによって導入される。

一部操作は Synchronize イベントも導入し得る。Synchronize event はフィールドを持たず、他イベントの許容順序を直接制約するためだけに存在する。

Shared Data Block イベントと Synchronize イベントに加えて、ホスト固有イベントが存在する。

ReadSharedMemory / WriteSharedMemory / ReadModifyWriteSharedMemory イベントの範囲はその [[ByteIndex]] から [[ByteIndex]] + [[ElementSize]] - 1 までの連続整数集合とする。2 つのイベントの範囲が同じ [[Block]] を持ち要素毎に等しいとき、それらの範囲は等しい。2 つのイベントの範囲が同じ [[Block]] を持ち、範囲が等しくなく かつ 交差が空でないとき、範囲は重複 (overlapping) する。2 つのイベントの範囲が同じ [[Block]] を持たないか、範囲が等しくも重複もしていないとき、範囲は素 (disjoint) である。

Note 2

考慮すべきホスト固有同期イベント例:SharedArrayBuffer を一方のエージェントから他方へ送る(ブラウザでの postMessage など)、エージェントの開始と停止、共有メモリ以外のチャネルによるエージェントクラスタ内通信。特定の実行 execution において、それらイベントは host-synchronizes-with 厳密半順序を通じてホストにより提供される。さらにホストis-agent-order-before 関係に参加するため execution.[[EventList]]ホスト固有同期イベントを追加できる。

イベントは以下で定義する関係によって候補実行内で順序付けられる。

29.2 Agent Events レコード (Agent Events Records)

Agent Events Record は次のフィールドを持つ Record である。

Table 97: Agent Events Record フィールド (Agent Events Record Fields)
Field Name Value Meaning
[[AgentSignifier]] エージェント識別子 この順序付けに結果した評価を行ったエージェント。
[[EventList]] イベントの List 評価中にイベントがリストへ追加される。
[[AgentSynchronizesWith]] Synchronize イベントのペアの List 操作的意味論によって導入された Synchronize 関係。

29.3 Chosen Value レコード (Chosen Value Records)

Chosen Value Record は次のフィールドを持つ Record である。

Table 98: Chosen Value Record フィールド (Chosen Value Record Fields)
Field Name Value Meaning
[[Event]] Shared Data Block event この選択値のために導入された ReadSharedMemory または ReadModifyWriteSharedMemory イベント。
[[ChosenValue]] バイト値List 評価中に非決定的に選択されたバイト。

29.4 候補実行 (Candidate Executions)

candidate execution とは次のフィールドを持つエージェントクラスタ評価の Record である。

Table 99: Candidate Execution Record フィールド (Candidate Execution Record Fields)
Field Name Value Meaning
[[EventsRecords]] Agent Events RecordsList エージェントを評価中に追加されたイベントの List に対応付ける。
[[ChosenValues]] Chosen Value RecordsList ReadSharedMemory または ReadModifyWriteSharedMemory イベントを評価中に選択されたバイト値List に対応付ける。

empty candidate execution はフィールドが空 List である candidate execution Record である。

29.5 メモリーモデル用抽象操作 (Abstract Operations for the Memory Model)

29.5.1 EventSet ( execution )

The abstract operation EventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. events を空集合とする。
  2. execution.[[EventsRecords]] の各 Agent Events Record aer について
    1. aer.[[EventList]] の各イベント E について
      1. Eevents に追加する。
  3. events を返す。

29.5.2 SharedDataBlockEventSet ( execution )

The abstract operation SharedDataBlockEventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. events を空集合とする。
  2. EventSet(execution) の各イベント E について
    1. もし EReadSharedMemory / WriteSharedMemory / ReadModifyWriteSharedMemory イベントなら Eevents に追加する。
  3. events を返す。

29.5.3 HostEventSet ( execution )

The abstract operation HostEventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. events を空集合とする。
  2. EventSet(execution) の各イベント E について
    1. もし ESharedDataBlockEventSet(execution) に含まれないなら Eevents に追加する。
  3. events を返す。

29.5.4 ComposeWriteEventBytes ( execution, byteIndex, Ws )

The abstract operation ComposeWriteEventBytes takes arguments execution (a candidate execution), byteIndex (a non-negative integer), and Ws (a List of either WriteSharedMemory or ReadModifyWriteSharedMemory events) and returns a List of byte values. It performs the following steps when called:

  1. byteLocationbyteIndex とする。
  2. bytesRead を新しい空の List とする。
  3. Ws の各要素 W について
    1. 事前条件: W はその範囲に byteLocation を含む。
    2. payloadIndexbyteLocation - W.[[ByteIndex]] とする。
    3. もし WWriteSharedMemory イベントなら
      1. byteW.[[Payload]][payloadIndex] とする。
    4. それ以外
      1. 事前条件: WReadModifyWriteSharedMemory イベントである。
      2. bytesValueOfReadEvent(execution, W) とする。
      3. bytesModifiedW.[[ModifyOp]](bytes, W.[[Payload]]) とする。
      4. bytebytesModified[payloadIndex] とする。
    5. bytebytesRead に追加する。
    6. byteLocationbyteLocation + 1 に設定する。
  4. bytesRead を返す。
Note 1

read-modify-write 変更 [[ModifyOp]]ReadModifyWriteSharedMemory イベントを導入する Atomics オブジェクト上の関数プロパティによって与えられる。

Note 2

この抽象操作は書き込みイベントの Listバイト値List に合成する。ReadSharedMemory および ReadModifyWriteSharedMemory イベントのイベント意味論で使用される。

29.5.5 ValueOfReadEvent ( execution, R )

The abstract operation ValueOfReadEvent takes arguments execution (a candidate execution) and R (a ReadSharedMemory or ReadModifyWriteSharedMemory event) and returns a List of byte values. It performs the following steps when called:

  1. Wsexecution における reads-bytes-from(R) とする。
  2. 事前条件: WsR.[[ElementSize]] と同じ長さの WriteSharedMemory または ReadModifyWriteSharedMemory イベントの List
  3. ComposeWriteEventBytes(execution, R.[[ByteIndex]], Ws) を返す。

29.6 候補実行における関係 (Relations of Candidate Executions)

以下の関係と数学的関数は特定の候補実行をパラメータに取り、そのイベントを順序付ける。

29.6.1 is-agent-order-before

候補実行 execution における is-agent-order-before 関係は次を満たす最小のイベント上の関係である。

  • イベント ED について、execution.[[EventsRecords]] 内のある Agent Events Record aer が存在し aer.[[EventList]]ED が含まれ かつ EList 順序で D より前にあるなら、E is-agent-order-before D in execution
Note

各エージェントは評価中にエージェント毎の厳密な全順序でイベントを導入する。これはそれら厳密全順序の合併である。

29.6.2 reads-bytes-from

候補実行 execution における reads-bytes-from 関数は SharedDataBlockEventSet(execution) 内のイベントを同集合内のイベントの List に写像し次の条件を満たす数学的関数である。

候補実行は常に reads-bytes-from 関数を許容する。

29.6.3 reads-from

候補実行 execution における reads-from 関係は次を満たす最小のイベント上の関係である。

29.6.4 host-synchronizes-with

候補実行 execution における host-synchronizes-with 関係はホスト提供のホスト固有イベント上の厳密半順序で少なくとも次を満たす。

  • もし E host-synchronizes-with D in execution なら HostEventSet(execution) は ED を含む。
  • host-synchronizes-with と is-agent-order-before の合併にサイクルが存在しない。
Note 1

候補実行 execution 内のホスト固有イベント ED について、E host-synchronizes-with D in executionE happens-before D in execution を意味する。

Note 2

この関係はホストに追加の同期機構(HTML ワーカー間の postMessage など)を提供させる。

29.6.5 synchronizes-with

候補実行 execution における synchronizes-with 関係は次を満たす最小のイベント上の関係である。

  • イベント RW について、R reads-from W in execution, R.[[Order]]seq-cst, W.[[Order]]seq-cst, かつ RW が等しい範囲なら W synchronizes-with R in execution
  • execution.[[EventsRecords]] の各要素 eventsRecord について次が成り立つ。
    • イベント SSw について、eventsRecord.[[AgentSynchronizesWith]] が (S, Sw) を含むなら S synchronizes-with Sw in execution
  • イベント ED について、execution.[[HostSynchronizesWith]] が (E, D) を含むなら E synchronizes-with D in execution
Note 1

メモリーモデル文献の慣例により、候補実行 execution では書き込みイベントが読み取りイベントを synchronizes-with する。

Note 2

候補実行 execution では init イベントはこの関係に参加せず、代わりに happens-before により直接制約される。

Note 3

候補実行 execution において reads-from で関連する全 seq-cst イベントが synchronizes-with で関連するとは限らない。等しい範囲を持つイベントのみが synchronizes-with で関連する。

Note 4

候補実行 executionShared Data Block イベント RWW synchronizes-with R の場合、RW 以外の書き込みからも reads-from し得る。

29.6.6 happens-before

候補実行 execution における happens-before 関係は次を満たす最小のイベント上の関係である。

  • イベント ED について、次のいずれかが真なら E happens-before D in execution

Note

happens-before は agent-order の上位集合であるため、候補実行は ECMAScript の単一スレッド評価意味論と整合する。

29.7 有効な実行の性質 (Properties of Valid Executions)

29.7.1 Valid Chosen Reads

候補実行 execution が valid chosen reads を持つとは次のアルゴリズムが true を返す場合である。

  1. SharedDataBlockEventSet(execution) の各 ReadSharedMemory または ReadModifyWriteSharedMemory イベント R について
    1. chosenValueRecordexecution.[[ChosenValues]] のうち [[Event]] フィールドが R である要素とする。
    2. chosenValuechosenValueRecord.[[ChosenValue]] とする。
    3. readValueValueOfReadEvent(execution, R) とする。
    4. chosenLenchosenValue の要素数とする。
    5. readLenreadValue の要素数とする。
    6. もし chosenLenreadLen なら
      1. false を返す。
    7. もし 区間 [0, chosenLen) のある整数 i について chosenValue[i] ≠ readValue[i] なら
      1. false を返す。
  2. true を返す。

29.7.2 Coherent Reads

候補実行 execution が coherent reads を持つとは次のアルゴリズムが true を返す場合である。

  1. SharedDataBlockEventSet(execution) の各 ReadSharedMemory または ReadModifyWriteSharedMemory イベント R について
    1. Wsreads-bytes-from(R) in execution とする。
    2. byteLocationR.[[ByteIndex]] とする。
    3. Ws の各要素 W について
      1. もし R happens-before W in execution なら
        1. false を返す。
      2. もし byteLocation をその範囲に含む WriteSharedMemory または ReadModifyWriteSharedMemory イベント V が存在し、W happens-before V かつ V happens-before R in execution なら
        1. false を返す。
      3. byteLocationbyteLocation + 1 に設定する。
  2. true を返す。

29.7.3 Tear Free Reads

候補実行 execution が tear free reads を持つとは次のアルゴリズムが true を返す場合である。

  1. SharedDataBlockEventSet(execution) の各 ReadSharedMemory または ReadModifyWriteSharedMemory イベント R について
    1. もし R.[[NoTear]]true なら
      1. 事前条件: R.[[ByteIndex]]R.[[ElementSize]] で割った余りは 0。
      2. R reads-from W in execution であり W.[[NoTear]]true である各イベント W について
        1. もし RW が等しい範囲を持ち、RW が同じ Shared Data Block event でなく、R reads-from V in execution を満たす等しい範囲と [[NoTear]]true のイベント V が存在するなら
          1. false を返す。
  2. true を返す。
Note

イベントの [[NoTear]] フィールドは整数 TypedArray へのアクセスで導入されたとき true、浮動小数点 TypedArray または DataView で導入されたとき false

直感的説明: メモリ範囲が整数 TypedArray によりアラインされた形でアクセスされたとき、その範囲に対する単一の書き込みイベントが同範囲の他の書き込みイベントとのデータ競合で「勝つ」必要がある。より厳密には、アラインされた読み取りイベントが、同一範囲を持つ複数の異なる書き込みイベントのバイトを混合した値を読んではならない。なお、アラインされた読み取りイベントが重複範囲を持つ複数の書き込みイベントから読む可能性は残る。

29.7.4 Sequentially Consistent Atomics

候補実行 execution において、is-memory-order-beforeEventSet(execution) 内の全イベント上の厳密全順序で次を満たす。

  • イベント ED について、E happens-before D in execution なら E is-memory-order-before D in execution
  • R reads-from W in execution であるイベント RW について、SharedDataBlockEventSet(execution) 内に WriteSharedMemory または ReadModifyWriteSharedMemory イベント V が存在し、V.[[Order]]seq-cst, W is-memory-order-before V, V is-memory-order-before R であり、かつ以下のいずれかが真である状況は存在しない。

    Note 1

    この節は等しい範囲における seq-cst イベントを追加制約する。

  • SharedDataBlockEventSet(execution) 内の各 WriteSharedMemory または ReadModifyWriteSharedMemory イベント W について、W.[[Order]]seq-cst なら、W より memory-order 前に等しい範囲で無限個の ReadSharedMemory または ReadModifyWriteSharedMemory イベントが存在することはない。

    Note 2

    この節とエージェントの前進性保証により、seq-cst 書き込みが有限時間で等しい範囲の seq-cst 読み取りに可視化されるという活性 (liveness) 条件を確保する。

候補実行は is-memory-order-before 関係を許容するなら sequentially consistent atomics を持つ。

Note 3

is-memory-order-before は EventSet(execution) の全イベントを含むが、execution 内で happens-before または synchronizes-with によって制約されないものは順序中の任意位置に現れてよい。

29.7.5 Valid Executions

候補実行 execution が有効実行 (execution) であるとは、以下すべてが真であること。

  • ホストexecution に対する host-synchronizes-with 関係を提供する。
  • execution が厳密半順序である happens-before 関係を許容する。
  • execution が valid chosen reads を持つ。
  • execution が coherent reads を持つ。
  • execution が tear free reads を持つ。
  • execution が sequentially consistent atomics を持つ。

全てのプログラムは少なくとも 1 つの有効実行を持つ。

29.8 競合 (Races)

実行 executionSharedDataBlockEventSet(execution) に含まれるイベント ED について、次のアルゴリズムが true を返すとき EDrace にある。

  1. もし ED が同一の Shared Data Block event でないなら
    1. もし E happens-before D in execution かつ D happens-before E in execution の双方が成り立たないなら
      1. もし ED が共に WriteSharedMemory または ReadModifyWriteSharedMemory イベントで かつ ED の範囲が素でないなら
        1. true を返す。
      2. もし E reads-from D in execution または D reads-from E in execution なら
        1. true を返す。
  2. false を返す。

29.9 データ競合 (Data Races)

実行 executionSharedDataBlockEventSet(execution) に含まれるイベント ED について、次のアルゴリズムが true を返すとき EDdata race にある。

  1. もし EDrace in execution にあるなら
    1. もし E.[[Order]]seq-cst ではない または D.[[Order]]seq-cst ではないなら
      1. true を返す。
    2. もし ED が重複する範囲を持つなら
      1. true を返す。
  2. false を返す。

29.10 データ競合の不存在 (Data Race Freedom)

実行 executiondata race free とは SharedDataBlockEventSet(execution) 内に data race にある 2 つのイベントが存在しないこと。

プログラムが data race free とはそのすべての実行が data race free であること。

メモリーモデルは data race free プログラムの全イベントについて逐次的一貫性を保証する。

29.11 共有メモリ利用指針 (Shared Memory Guidelines)

Note 1

以下は共有メモリを扱う ECMAScript プログラマ向けガイドラインである。

プログラムを data race free に保つ(すなわち同一メモリ位置に対する並行する非 atomic 操作が不可能であるようにする)ことを推奨する。Data race free プログラムは各エージェントの評価意味論ステップが互いにインターリーブされる意味論(インターリービング意味論)を持つ。Data race free プログラムではメモリーモデルの詳細を理解する必要はない。詳細は ECMAScript をより良く書くための直観をほぼ与えない。

より一般には、プログラムが data race free でなくとも、atomic 操作がどのデータ競合にも巻き込まれず、競合する操作がすべて同じアクセスサイズであれば予測可能な振る舞いを持ち得る。Atomic 操作を競合に巻き込まない最も簡単な方法は、atomic と非 atomic の操作が異なるメモリセルを使用し、異なるサイズの atomic アクセスを同じセルに同時利用しないようにすることである。実質的にプログラムは共有メモリを可能な限り強い型付けがあるものとして扱うべきである。依然として競合する非 atomic アクセスの順序やタイミングに依存することはできないが、メモリを強く型付けとして扱えば競合するアクセスは「tear」(値のビット断片の混在)しない。

Note 2

以下は共有メモリを使用するプログラムにコンパイラ変換を適用する ECMAScript 実装者向けガイドラインである。

単一エージェント環境で有効なほとんどのプログラム変換をマルチエージェント環境でも許容することが望ましい。これによりマルチエージェントプログラムにおける各エージェントの性能が単一エージェント環境と同様に良好となる。しばしばこれら変換は判断が難しい。以下にメモリーモデルによって含意される(またはそれより強い)規範的意図を持つが網羅的ではない規則を示す。これらは is-agent-order-before 関係を構成するイベントが導入される以前のプログラム変換に適用されることを意図する。

agent-order slice を単一エージェントに関わる is-agent-order-before 関係の部分集合とする。

読み取りイベントの possible read values を、そのイベントに対する全有効実行における ValueOfReadEvent の値集合とする。

共有メモリが存在しない場合に有効なエージェント順スライスの任意の変換は、以下の例外を除き共有メモリ存在下でも有効である。

  • Atomic は石版に刻まれている: プログラム変換はエージェント順スライス内の seq-cst イベントを unordered 操作と再順序付けしてはならず、seq-cst 操作同士を再順序付けしてもならず、seq-cst 操作を is-agent-order-before 関係から除去してもならない。

    (実際には並べ替え禁止はコンパイラに全 seq-cst 操作が同期であり最終的な is-memory-order-before 関係に含まれると仮定させる。これは相互エージェント解析不在で通常仮定せざるを得ない。さらに呼び出し先の memory-order への影響が未知な呼び出しは seq-cst 操作を含み得ると仮定させる。)

  • 読み取りは安定: 任意の共有メモリ読み取りは 1 回の実行で単一の値のみ観測しなければならない。

    (例: プログラム上意味的に 1 回の読みを複数回実行した場合、後続で観測される値はそのうち 1 つのみ許される。Rematerialization として知られる変換はこの規則に違反し得る。)

  • 書き込みは安定: 共有メモリへの全ての観測可能な書き込みは実行中のプログラム意味論から導かれていなければならない。

    (例: より大きな場所での read-modify-write を用いて小さなデータを書いたり、プログラムが書き得ない値の書き込み、他エージェントにより上書きされ得る位置に直前に読み取った値をそのまま書き戻したりしてはならない。)

  • Possible read values は空であってはならない: プログラム変換は共有メモリ読み取りの possible read values を空集合にしてはならない。

    (直観に反して、この規則は実際には書き込み上の変換を制約する。書き込みは読み取りイベントにより読まれることでメモリーモデル上の効力を持つため。例えば書き込みは seq-cst 操作 2 つの間で移動・合併・時に再順序付けできるが、ある位置を更新する全ての書き込みを除去することはできない;何らかの書き込みは残さねばならない。)

依然として有効な変換例: 同一位置への複数の非 atomic 読み取りのマージ、非 atomic 読み取りの再順序付け、投機的非 atomic 読み取りの導入、同一位置への複数非 atomic 書き込みのマージ、異なる位置への非 atomic 書き込みの再順序付け、非 atomic 読み取りのループ外へのホイスト(終了性に影響があっても)。一般にエイリアスされた TypedArray は位置が異なることの証明を難しくする。

Note 3

以下は共有メモリアクセスに対して機械語生成を行う ECMAScript 実装者向けガイドラインである。

ARM や Power より弱くないメモリーモデルを持つアーキテクチャでは、非 atomic store / load は素の store / load 命令にコンパイルできる。Atomic store / load は逐次的一貫性を保証する命令にコンパイルできる。そうした命令が無い場合、フェンス(両側への配置など)を利用する。Read-modify-write 操作は対象アーキテクチャの read-modify-write 命令列(x86 の LOCK 接頭辞、ARM の load-exclusive/store-exclusive、Power の load-link/store-conditional 等)にコンパイルできる。

具体的に、メモリーモデルは以下のコード生成を許容する意図である。

  • プログラム中の全 atomic 操作は必要であると仮定する。
  • Atomic 操作は互い、または非 atomic 操作と再順序付けされない。
  • 関数呼び出しは常に atomic 操作を行うと仮定する。
  • Atomic 操作はより大きなデータ上の read-modify-write を用いて実装されず、適切なサイズの atomic 操作がプラットフォームにない場合は non-lock-free atomics として実装される。(全ての興味あるサイズの通常メモリアクセス命令は存在すると仮定。)

素朴なコード生成パターン:

  • 通常の load/store は単一の load/store 命令。
  • ロックフリー atomic load/store は完全フェンス、通常 load/store、完全フェンス。
  • ロックフリー atomic read-modify-write は完全フェンス、atomic read-modify-write 命令列、完全フェンス。
  • 非ロックフリー atomic はスピンロック獲得、完全フェンス、非 atomic load/store 列、完全フェンス、スピンロック解放。

この写像は、アドレス範囲上の atomic 操作が非 atomic 書き込みまたは異なるサイズの atomic 操作と競合しない限り正しい。それで十分である:メモリーモデルは競合に関与する atomic 操作を非 atomic とみなす。一方素朴な写像は強い:メモリーモデルが実際には保証しない逐次的一貫フェンスとして atomic 操作を使用できる。

これら基本パターンへの局所的改善も、メモリーモデル制約に従う限り許容される。例:

  • 冗長フェンスの除去(x86 では load/store 周りのフェンス省略など、LOCK 接頭辞命令使用により read-modify-write でフェンス不要)や、弱いフェンスの使用。
  • 多くのプラットフォームは必要な全サイズのロックフリー atomic をサポート。非ロックフリーが必要なら atomic 操作本体を囲むフェンスはロック獲得/解放に折り込める。最も簡単なのは SharedArrayBuffer 毎に単一のロック語を持つこと。
  • 2 つの連続フェンスは単一フェンスと同等な場合が多く、連続する 2 つの atomic 操作生成時は間に 1 つで良い。x86 では atomic store 連続間のフェンスを省略可能など。