?uem/p1-90`内存一致性模型,或称内存模型,规定了通过访问由 SharedArrayBuffer 支持的
内存模型被定义为对求值期间由 SharedArrayBuffer 上的
共享内存访问(读取和写入)分为以下定义的两组:原子访问和数据访问。原子访问是顺序一致的,也就是说,
不支持弱于顺序一致但强于无序的排序方式,例如 release-acquire。
Shared Data Block 事件是 ReadSharedMemory、WriteSharedMemory 或 ReadModifyWriteSharedMemory
| 字段名称 | 值 | 含义 |
|---|---|---|
| [[Order]] | ||
| [[NoTear]] | a Boolean | 是否允许此事件从与此事件具有相同 |
| [[Block]] | a |
事件所操作的数据块。 |
| [[ByteIndex]] | a non-negative integer | [[Block]] 中读取操作的字节地址。 |
| [[ElementSize]] | a non-negative integer | 读取操作的大小。 |
| 字段名称 | 值 | 含义 |
|---|---|---|
| [[Order]] | ||
| [[NoTear]] | a Boolean | 是否允许多个与此事件具有相同 |
| [[Block]] | a |
事件所操作的数据块。 |
| [[ByteIndex]] | a non-negative integer | [[Block]] 中写入操作的字节地址。 |
| [[ElementSize]] | a non-negative integer | 写入操作的大小。 |
| [[Payload]] | a |
供其他事件读取的 |
| 字段名称 | 值 | 含义 |
|---|---|---|
| [[Order]] | 读-修改-写事件始终是顺序一致的。 | |
| [[NoTear]] | 读-修改-写事件不能发生撕裂。 | |
| [[Block]] | a |
事件所操作的数据块。 |
| [[ByteIndex]] | a non-negative integer | [[Block]] 中读-修改-写操作的字节地址。 |
| [[ElementSize]] | a non-negative integer | 读-修改-写操作的大小。 |
| [[Payload]] | a |
要传递给 [[ModifyOp]] 的 |
| [[ModifyOp]] | a read-modify-write modification function | 从读取到的 |
Shared Data Block 事件由
令 Shared Data Block 事件 e 的内存范围为从 e.[[ByteIndex]](
Agent Events Record 是具有以下字段的
| 字段名称 | 值 | 含义 |
|---|---|---|
| [[AgentSignifier]] | an agent signifier | 其求值产生此排序的 |
| [[EventList]] | a |
事件在求值期间追加到该 |
| [[AgentSynchronizesWith]] | a |
由操作语义引入的 |
Chosen Value Record 是具有以下字段的
| 字段名称 | 值 | 含义 |
|---|---|---|
| [[Event]] | a |
为此选定值引入的 |
| [[ChosenValue]] | a |
求值期间非确定性选择的字节。 |
| 字段名称 | 值 | 含义 |
|---|---|---|
| [[EventsRecords]] | a |
将 |
| [[ChosenValues]] | a |
将 |
读-修改-写修改 [[ModifyOp]] 由 Atomics 对象上会引入
此
以下关系和数学函数以某个特定
对于
对于
对于
对于
对于
对于
对于
在
在
对于
对于
对于事件 eventA 和 eventB,如果以下任一条件为真,则 eventA happens-before eventB in execution。
由于 happens-before 是 agent-order 的超集,因此
如果以下算法返回
如果以下算法返回
如果以下算法返回
当
直观地说,此要求意味着,当通过
对于
对于满足 readEvent
此条款进一步约束具有相等
对于
如果
虽然 is-memory-order-before
如果以下所有条件均为真,则
所有程序至少具有一个有效执行。
对于执行 execution 以及
对于执行 execution 以及
如果
如果程序的所有执行都是无数据竞争的,则该程序是无数据竞争的。
以下是供使用共享内存的 ECMAScript 程序员参考的指南。
建议使程序保持无
更一般地说,即使程序并非无
以下是供为使用共享内存的程序编写编译器转换的 ECMAScript 实现者参考的指南。
为了确保多
令agent-order 切片为
令
在没有共享内存时有效的任何 agent-order 切片转换,在存在共享内存时也有效,但以下情况除外。
原子操作不可撼动:程序转换不得导致 [[Order]] 为
(实际上,对重排的禁止迫使编译器假定每个
读取必须稳定:任何给定的共享内存读取在一次执行中都只能观察到一个值。
(例如,如果程序中语义上是单次读取的操作被执行多次,那么程序随后只能观察读取到的其中一个值。称为重物化的转换可能违反此规则。)
写入必须稳定:对共享内存的所有可观察写入都必须源自一次执行中的程序语义。
(例如,转换不得引入某些可观察写入,例如通过对更大位置使用读-修改-写操作来写入较小数据、向内存写入程序不可能写入的值,或者在某位置可能在读取后已被另一
可能读取值必须非空:程序转换不能导致共享内存读取的可能读取值变为空。
(反直觉的是,此规则实际上
仍然有效的转换示例包括:合并对同一位置的多个非原子读取、重排非原子读取、引入推测性非原子读取、合并对同一位置的多个非原子写入、重排对不同位置的非原子写入,以及即使会影响终止性也将非原子读取提升到循环之外。一般而言,需要
以下是供为共享内存访问生成机器代码的 ECMAScript 实现者参考的指南。
对于LOCK 前缀的指令、ARM 上的 load-exclusive/store-exclusive 指令,以及 Power 上的 load-link/store-conditional 指令。
具体来说,
朴素代码生成使用以下模式:
只要某个
在
LOCK 前缀的指令。许多平台具有多种强度的屏障,可以在特定上下文中使用较弱的屏障而不会破坏顺序一致性。