?um/p1-90`メモリ一貫性モデル、または メモリモデル は、SharedArrayBuffer をバックとする
メモリモデルは、SharedArrayBuffer に対する
この節では、SharedArrayBuffer に対する
共有メモリアクセス(読み書き)は後述の定義に従い atomic アクセスと data アクセスの 2 群に分けられる。Atomic アクセスは逐次的一貫性を持つ、すなわちエージェントクラスタ内の全エージェントが合意する厳密な全順序が存在する。非 atomic アクセスは全エージェントが合意する厳密な全順序を持たず、すなわち unordered である。
逐次的一貫性より弱く、unordered より強い順序(例: release-acquire)はサポートされない。
共有データブロックイベントは、ReadSharedMemory、WriteSharedMemory、またはReadModifyWriteSharedMemoryレコードのいずれかです。読み出しイベントは、ReadSharedMemory または ReadModifyWriteSharedMemory のいずれかです。書き込みイベントは、WriteSharedMemory または ReadModifyWriteSharedMemory のいずれかです。
| フィールド名 | 値 | 意味 |
|---|---|---|
| [[Order]] | ||
| [[NoTear]] | ブール値 | このイベントが、自身と等しい |
| [[Block]] | 共有データブロック | イベントが操作するブロック。 |
| [[ByteIndex]] | 0 以上の |
[[Block]] 内での読み取りのバイトアドレス。 |
| [[ElementSize]] | 0 以上の |
読み取りのサイズ。 |
| フィールド名 | 値 | 意味 |
|---|---|---|
| [[Order]] | ||
| [[NoTear]] | ブール値 | このイベントが、自身と等しい |
| [[Block]] | 共有データブロック | イベントが操作するブロック。 |
| [[ByteIndex]] | 0 以上の |
[[Block]] 内での書き込みのバイトアドレス。 |
| [[ElementSize]] | 0 以上の |
書き込みのサイズ。 |
| [[Payload]] | 他のイベントによって読み取られる |
| Field Name | Value | Meaning |
|---|---|---|
| [[Order]] | Read-modify-write イベントは常に逐次的一貫性。 | |
| [[NoTear]] | Read-modify-write イベントは tear しない。 | |
| [[Block]] | イベントが作用するブロック。 | |
| [[ByteIndex]] | 非負 |
[[Block]] 内での read-modify-write のバイト位置。 |
| [[ElementSize]] | 非負 |
read-modify-write のサイズ。 |
| [[Payload]] | [[ModifyOp]] に渡される |
|
| [[ModifyOp]] | 読み取った |
共有データブロックイベントは、
共有データブロックイベント e の メモリ範囲 とは、e.[[ByteIndex]](含む)から e.[[ByteIndex]] + e.[[ElementSize]](含まない)までの
考慮すべきpostMessage など)、エージェントの開始と停止、共有メモリ以外のチャネルによるエージェントクラスタ内通信。特定の実行 execution において、それらイベントは
イベントは以下で定義する関係によって候補実行内で順序付けられる。
Agent Events Record は次のフィールドを持つ
Chosen Value Record は次のフィールドを持つ
| Field Name | Value | Meaning |
|---|---|---|
| [[Event]] | この選択値のために導入された |
|
| [[ChosenValue]] | 評価中に非決定的に選択されたバイト。 |
candidate execution とは次のフィールドを持つエージェントクラスタ評価の
| フィールド名 | 値 | 意味 |
|---|---|---|
| [[EventsRecords]] | エージェントイベントレコードのリスト | エージェントを、評価中に追加された |
| [[ChosenValues]] | 選択された値レコードのリスト |
empty candidate execution はフィールドが空
The abstract operation EventSet takes argument execution (候補実行) and returns
The abstract operation SharedDataBlockEventSet takes argument execution (候補実行) and returns
The abstract operation HostEventSet takes argument execution (候補実行) and returns
The abstract operation ComposeWriteEventBytes takes arguments execution (候補実行), byteIndex (0 以上の
Read-Modify-Write の修飾 [[ModifyOp]] は、
この
The abstract operation ValueOfReadEvent takes arguments execution (a
以下の関係および数学関数は、特定の候補実行にパラメータ化され、その
候補実行 execution に対し、その is-agent-order-before 関係は、次の条件を満たす
各エージェントは、評価中にエージェントごとの厳密な全順序でイベントを導入します。これは、それらの厳密な全順序の和集合です。
候補実行 execution に対し、その reads-bytes-from 関数は、
候補実行は常に reads-bytes-from 関数を持ちます。
候補実行 execution に対し、その reads-from 関係は、次の条件を満たす
候補実行 execution に対し、その host-synchronizes-with 関係は、次を少なくとも満たす、
候補実行 execution の二つの
この関係は、postMessage などの追加的な同期機構を提供することを許可します。
候補実行 execution に対し、その synchronizes-with 関係は、次の条件を満たす
候補実行 execution において、
候補実行 execution において、
候補実行 execution における
候補実行 execution に対し、その happens-before 関係は、次の条件を満たす
イベント E および D について、execution において E happens-before D であるのは、次のいずれかの条件が成り立つ場合です。
happens-before は
候補実行 execution が妥当な選択読みを持つとは、次のアルゴリズムが
候補実行 execution がコヒーレントリードを持つとは、次のアルゴリズムが
候補実行 execution がティアフリーリードを持つとは、次のアルゴリズムが
直感的には、この要件は、
候補実行 execution に対し、is-memory-order-before は
execution において R
この項は等しい
候補実行が is-memory-order-before 関係を持つ場合、それは逐次一貫性のあるアトミック操作を持つという。
is-memory-order-before は
候補実行 execution は、次のすべてが成り立つ場合、有効な実行(単に実行とも呼ぶ)である。
すべてのプログラムは少なくとも1つの有効な実行を持つ。
実行 execution および
実行 execution および
実行 execution が データ競合なし(data race free) であるとは、
すべての実行がデータ競合なしであれば、そのプログラムはデータ競合なしである。
以下は共有メモリを扱う ECMAScript プログラマー向けの指針です。
プログラムはデータ競合なしに保つこと(すなわち、同一メモリ位置に対する非アトミック操作が並行して発生しないこと)が推奨されます。データ競合なしプログラムは、各エージェントの評価意味論が交互にインターリーブされる意味論になります。データ競合なしであれば、
より一般的には、プログラムがデータ競合なしでなくとも、アトミック操作が競合に関与せず、競合する操作がすべて同じアクセスサイズであれば、予測可能な挙動となる場合があります。もっとも単純なのは、アトミックと非アトミックの操作で異なるメモリセルを使う・異なるサイズのアトミックアクセスで同一セルを同時にアクセスしないようにすることです。すなわち、プログラムは可能な限り共有メモリを強く型付けされたものとして扱うべきです。依然として競合する非アトミックアクセスの順序やタイミングには依存できませんが、メモリを強く型付けとして扱えば競合アクセスで「ティア」(値のビットが混ざり合う)が発生しません。
以下は共有メモリ利用プログラムのコンパイラ変換を行う ECMAScript 実装者向けの指針です。
シングルエージェント環境で有効なほとんどのプログラム変換を、マルチエージェント環境でも許可することが望ましい。これにより、マルチエージェントプログラムにおける各エージェントの性能が、シングルエージェント環境と同様に良好であることが保証される。多くの場合、これらの変換の妥当性を判断するのは難しい。本節では、プログラム変換に関するいくつかの規則を示す。これらの規則は規範的に(つまり
エージェント順序スライスとは、
ある
共有メモリなしの場合に有効なエージェント順序スライスの変換は、下記例外を除き、共有メモリがある場合でも有効である。
アトミックは常にそのまま: プログラム変換によって、[[Order]] が
(実際には、この順序変更の禁止によって、コンパイラはすべての
読み出しの安定性: 各共有メモリ読み出しは、同一実行中つねに一つの値しか観測できないこと。
(例えば、意味的に単一の読み出しが複数回実行された場合、その後プログラムが観測できるのはそのうちいずれか一つだけになること。他の値も観測できるような変換(リマテリアリゼーション)は違反となる。)
書き込みの安定性: 共有メモリへのすべての観測可能な書き込みは、各実行のプログラム意味論に従っていなければならない。
(例えば、リードモディファイライトによる大きい単位での書き込みで小さい値を書き込む・本来書けない値を書き込む・読み出した値を読み出し後に他のエージェントが上書きした可能性のあるアドレスに再度書き戻すなどによって、観測可能な書き込みを増やしてはならない。)
可能な読み値は空であってはならない: プログラム変換は、共有メモリ読み出しの可能な読み値が空になる原因になってはならない。
(これは直感に反するが、実際にはこの規則が書き込み変換を強く制限する。
妥当な変換例:同一アドレスへの複数の非アトミック読みをまとめる・非アトミック読みに順序をつけず並び替える・投機的な非アトミック読みを導入する・同一アドレスへの複数の非アトミック書きをまとめる・異なるアドレスへの非アトミック書きの順序を並び替える・巻き込み終端影響があってもループの外に非アトミック読みに抜き出す、など。一般に
以下は共有メモリアクセスに対する機械語生成を行う ECMAScript 実装者向けの指針です。
ARMやPowerより弱くない
単純なコード生成パターン:
この対応は、アトミック操作が非アトミック書き込みや異なるサイズのアトミック操作と競合しなければ正しい。現実にはそれで十分であり、
この基本パターンへのローカルな改善も、