Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

重学js —— 内存模型 #134

Open
lizhongzhen11 opened this issue Jul 25, 2020 · 0 comments
Open

重学js —— 内存模型 #134

lizhongzhen11 opened this issue Jul 25, 2020 · 0 comments
Labels
js基础 Good for newcomers 重学js 重学js系列 规范+MDN

Comments

@lizhongzhen11
Copy link
Owner

内存模型

内存一致性模型,也叫 内存模型,指定通过访问由 SharedArrayBuffer 支持的 TypedArray 实例以及通过 Atomics 对象上的方法产生的 Shared Data Block 事件的可能顺序。当程序没有数据争用,事件的顺序显示为顺序一致,即每个 代理 的动作交错。当程序存在数据争用,共享内存操作可能会出现顺序不一致。例如,程序可能会表现出违反因果关系的行为和其他怪异的地方。这些怪异来自编译器转换和CPU的设计(例如乱序执行和推测)。内存模型既定义了程序表现出顺序一致行为的精确条件,也定义了从数据竞争中读取的可能值。也就是说,没有不确定的行为。

内存模型被定义为对求值过程中 SharedArrayBuffer 上的 抽象操作Atomics 对象上的方法所引入的事件的关系约束。

本节提供了针对 SharedArrayBuffers 上的抽象操作所引入的事件的公理(不言自明的)模型。 需要强调的是,与规范的其余部分不同,该模型无法通过算法表达。抽象操作对事件的不确定性引入是ECMAScript求值的操作语义与内存模型的公理语义之间的接口。这些事件的语义是通过考虑求值中所有事件的图来定义的。 这些既不是静态语义也不是运行时语义。没有经过证明的算法实现,而是一组约束,这些约束确定了允许还是不允许特定事件图。

内存模型基本原理

共享内存访问(读取和写入)分为以下两组,原子访问和数据访问。原子访问是顺序一致的,即,代理群集 中所有代理都同意对事件进行严格的总排序。非原子访问没有所有代理都同意的严格总排序,即未排序。

不支持弱于顺序一致且强于无序的排序,例如发布获取。

Shared Data Block eventReadSharedMemoryWriteSharedMemoryReadModifyWriteSharedMemory 记录 其中之一。

ReadSharedMemory Event字段

字段名 含义
[[Order]] SeqCst / Unordered 事件的内存模型保证的最弱排序
[[NoTear]] Boolean值 是否允许此事件从与该事件相等的范围内的多个写入事件中读取
[[Block]] Shared Data Block 事件运行所在的块
[[ByteIndex]] 非负整数 [[Block]] 的读取字节地址
[[ElementSize]] 非负整数 读取的大小

WriteSharedMemory Event字段

字段名 含义
[[Order]] SeqCst / Unordered / Init 事件的内存模型保证的最弱排序
[[NoTear]] Boolean值 是否允许从与其范围相等的多个读取事件中读取此事件
[[Block]] Shared Data Block 事件运行所在的块
[[ByteIndex]] 非负整数 [[Block]] 的写入字节地址
[[ElementSize]] 非负整数 写入的大小
[[Payload]] List 被其他事件读取的字节值列表

ReadModifyWriteSharedMemory Event字段

字段名 含义
[[Order]] SeqCst 读-修改-写事件总是顺序一致的
[[NoTear]] true 读-修改-写事件不能撕裂
[[Block]] Shared Data Block 事件运行所在的块
[[ByteIndex]] 非负整数 [[Block]] 的读-修改-写字节地址
[[ElementSize]] 非负整数 读-修改-写的大小
[[Payload]] List 传给 [[ModifyOp]] 字节值列表
[[ModifyOp]] 读-修改-写函数 一个抽象闭包,它从读取的字节值列表和 [[Payload]] 中返回修改后的字节值列表

这些事件通过 抽象操作 或原子对象上的方法引入的。

一些操作可能还会引入 Synchronize 事件。Synchronize event 没有字段,存在纯粹是为了直接限制其他事件的允许顺序。

除了 Shared Data BlockSynchronize event,还有环境特定事件。

假设 ReadSharedMemoryWriteSharedMemoryReadModifyWriteSharedMemory 事件的范围是从 [[ByteIndex]][[ByteIndex]] + [[ElementSize]] - 1 的连续整数的集合。当两个事件具有相同的 [[Block]] 并且元素范围相等时,这两个事件的范围相等。当事件具有相同的 [[Block]] 并且它们的范围不相等,同时它们的交集非空,那么这两个事件的范围重叠。当事件具有不同的 [[Block]] 并且它们的范围即不相等也不相交,则这两个事件不相交。

代理事件记录

字段名 含义
[[AgentSignifier]] 接受相等测试的值 求值导致此排序的 代理
[[EventList]] 事件 列表 在求值期间,事件会添加到列表中
[[AgentSynchronizesWith]] 同步事件的 列表 同步操作语义引入的关系

选择的值记录

字段名 含义
[[Event]] Shared Data Block event 为该选择的值引入的 ReadSharedMemoryReadModifyWriteSharedMemory 事件
[[ChosenValue]] 字节值 列表 求值期间不确定地选择的字节

候选执行

字段名 含义
[[EventsRecords]] 代理 事件记录 列表 将代理映射到求值期间附加的事件列表
[[ChosenValues]] 选择的值记录 列表 ReadSharedMemoryReadModifyWriteSharedMemory 事件映射到求值期间被选中的字节值列表
[[AgentOrder]] agent-order Relation agent-order
[[ReadsBytesFrom]] reads-bytes-from 数学函数 reads-bytes-from
[[ReadsFrom]] reads-from Relation reads-from
[[HostSynchronizesWith]] host-synchronizes-with Relation host-synchronizes-with
[[SynchronizesWith]] synchronizes-with Relation synchronizes-with
[[HappensBefore]] happens-before Relation happens-before

候选执行的关系

agent-order

对于候选执行 executionexecution.[[AgentOrder]] 是满足以下条件的最小事件关系:

  • 对于 EventSet(execution) 中的每对(E,D),如果 execution.[[EventsRecords]] 中存在 代理事件记录 aer 使得 ED 都在 aer.[[EventList]] 中且 Eaer.[[EventList]] 中排在 D 之前。

reads-bytes-from

对于候选执行 executionexecution.[[ReadsBytesFrom]] 是数学函数,可将 SharedDataBlockEventSet(execution) 中的事件映射到满足以下条件的 SharedDataBlockEventSet(execution) 中的事件列表:

  • 对于 SharedDataBlockEventSet(execution) 中的每个 ReadSharedMemoryReadModifyWriteSharedMemory 事件 Rexecution.[[ReadsBytesFrom]](R) 是一个长度等于 WriteSharedMemoryReadModifyWriteSharedMemory 事件 WsR.[[ElementSize]] 的列表
    • Ws 中每个事件 W,其索引为 i,在 Ws 范围内都有 R.[[ByteIndex]] + i
    • R 不在 Ws

reads-from

对于候选执行 executionexecution.[[ReadsFrom]] 是满足以下条件的最小事件关系:

  • 对于 SharedDataBlockEventSet(execution) 中的每对(R,W),如果 W 处于 execution.[[ReadsBytesFrom]](R) 中,则(R,W)处于 execution.[[ReadsFrom]]

host-synchronizes-with

对于候选执行 executionexecution.[[HostSynchronizesWith]] 是环境提供的有关环境特定事件的严格偏序,至少满足以下条件:

  • 如果(E, D)处于 execution.[[HostSynchronizesWith]] 中,EDHostEventSet(execution) 中
  • execution.[[HostSynchronizesWith]]execution.[[AgentOrder]] 的并集没有循环

synchronizes-with

对于候选执行 executionexecution.[[SynchronizesWith]] 是满足以下条件的最小事件关系:

  • 对于 execution.[[ReadsFrom]] 中的 (R, W) 对,如果 R.[[Order]]SeqCstW.[[Order]]SeqCstRW 有相同的范围,则(W, R)处于 execution.[[SynchronizesWith]]
  • 遍历 execution.[[EventsRecords]] 中的元素,别名 eventsRecord
    • 对于 eventsRecord.[[AgentSynchronizesWith]] 中的(S, Sw)对,(S, Sw)处于 execution.[[SynchronizesWith]]
  • 对于 execution.[[HostSynchronizesWith]] 的(E, D)对,(E, D)处于 execution.[[HostSynchronizesWith]]

happens-before

对于候选执行 executionexecution.[[HappensBefore]] 是满足以下条件的最小事件关系:

  • 对于 execution.[[AgentOrder]] 中的每对(E,D),(E,D)处于 execution.[[HappensBefore]]
  • 对于 execution.[[SynchronizesWith]] 中的每对(E,D),(E,D)处于 execution.[[HappensBefore]]
  • 对于 SharedDataBlockEventSet(execution) 中的每对(E,D),如果 E.[[Order]]InitED 范围相交,则(E,D)处于 execution.[[HappensBefore]]
  • 对于 EventSet(execution) 中的每对(E,D),如果存在事件 F 使得 (E, F) 对和 (F, D) 对都处于 execution.[[HappensBefore]] 中,则(E,D)处于 execution.[[HappensBefore]]

竞争

  1. 如果 E 不是 D
    1. 如果 (E, D) 对和 (D, E)对不在 execution.[[HappensBefore]] 中,
      1. 如果 ED 都是 WriteSharedMemoryReadModifyWriteSharedMemory 事件且 ED 没有不相交的范围,
        1. 返回 true
      2. 如果 (E, D) 对或 (D, E)对在 execution.[[ReadsFrom]] 中,
        1. 返回 true
  2. 返回 false

数据争用

  1. 如果 EDexecution 中处于竞争状态,
    1. 如果 E.[[Order]] 不是 SeqCstD.[[Order]] 不是 SeqCst
      1. 返回 true
    2. 如果 ED 范围相交,
      1. 返回 true
  2. 返回 false

数据争用自由

如果 SharedDataBlockEventSet(execution) 中没有事件在争用数据,则该执行 execution 是数据争用自由的。

如果程序的所有执行都不会数据争用,则该程序不会数据争用。

内存模型可确保无争用数据程序的所有事件的顺序一致性。

共享内存准则

@lizhongzhen11 lizhongzhen11 added js基础 Good for newcomers 重学js 重学js系列 规范+MDN labels Jul 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
js基础 Good for newcomers 重学js 重学js系列 规范+MDN
Projects
None yet
Development

No branches or pull requests

1 participant