2.2
这一节定义的是ARM64中定义的原子行为,这个可以看作是软硬件对原子行为定义的约定。
比如,2.2.1就定义了哪些是single-copy atomicity的,我理解这些定义的atomicity,在
软件开来应该都是原子的,这部分的定义和硬件怎么实现是无关的。
2.2.1
定义哪些操作是single-copy atomicity。我们挑选几条看下,第一条”A read that is
generated by a load instruction that loads a single general-purpose register
and …”,这条是说一个自然对齐的load指令一定是原子的。
2.2.1章节随后对所有的情况做了明确的定义,可以看到SIMD相关的定义占了大部分。
2.2.2
single-copy atomic访问的定义,就是定义single-copy atomic操作具有的性质: 1. 两个
single-copy atomic写,如果地址重叠,那么一定是一个整体上在另一个的前或后执行;
2. 两个single-copy atomic操作,一个读一个写,访问地址重叠,如果他们之间存在RAW关系,
写不会coherence-after读。(第二点原文应该这里有点笔误)
2.2.3
定义了multi-copy atomicity: 相同地址上的写是串行的,所有observer看到的写顺序是一样
的,所有observer是同步读到相同地址上的值的。
2.2.4
ARM定义Normal/device memory都不要求是multi-copy atomic。
2.2.5
多核之间,一个core执行的指令可能被另一个core修改,这一节的内容与此相关。
2.2.6
原子指令在实现上的一些约束。
2.3
这一节定义ARM的内存模型,为了方便说明,前面几节都是在介绍定义。
2.3.1
这一节是基础名词的定义,这些基础名词的定义和后面使用的地方是对应的,这里给出了所有
情况下的定义,我们这里先根据基本的定义,把握下定义的主线。所以,我们这里先不关注
某些特性的所有定义,比如和memory tag相关的定义,后面如果需要,我们在针对某个特性
整体考虑。
observer: 定义系统里可以发起读写请求的部件,比如CPU核或者外设。
common shareability domain:
location: 物理或者虚拟地址上的一个byte。
program order: 程序中所展现的指令之间的先后关系。
effects: 指令执行产生的影响,比如对寄存器有影响的叫register effect,对内存的影响
叫memory effect,这里的effect的分类有点随心所欲,似乎是哪里需要了,就在
这里加个定义,比如还有什么branching effect, TLBI effect, fault effect…
reads-from-register: 描述的是相同寄存器之间的RAW关系。
reads-from memory: 描述的是相同地址之间的RAW关系。没有提是不是相同observer,所以
这个关系是可以存在不同observer上的。
coherence order: 描述多个observer对相同地址写操作的关系。注意这里说这个是一个
“total order”,序理论上全序是指集合中任意两个元素都是可比的。
local read successor: 在一个observer上,描述相同地址之间的RAW关系。
local write successor: 在一个observer上,描述相同地址之间的写操作在写操作或读操作
之后的关系。
coherence-before:
在一个coherence order关系里,排在前面的写操作coherence-before后面的写操作。
store addr(W3)/load addr(R1)/store addr(W2)的关系里,如果R1 reads-from-memory W3,
W3 coherence-before W2, 那么R1 coherence-before W2。(什么鬼?)
对于store addr(W1) -> store addr(W2)和store addr(W1) -> load addr(R2),两种情况中
后者均没有对前者有coherence-before的关系。这里的load/store操作相同地址,并且先后
是program order。
(Tag相关的先不看)
observed-by: 在不同observer上,如果W2 coherence-after RW1,就是说在相同地址上W2
的访问排到RW1的后面,我们说RW1 observed-by W2。(W2和RW1需要是explict
的memory effect,先忽略Tag相关操作)
overlapping accesses: 就是地址访问有重叠。
single-copy-atomic-class: 所有single-copy-atomic触发的memory effects组成的集合。
single-copy-atomic-order-before: ??
implicit translation table descriptor(TTD) memory effects:
硬件对页表内存做隐式内存访问产生的effect,具体上有page table walk和对access/dirty
bit的修改。
hardware update effect: 特指对access/dirty bit修改产生的effect。基于这个还定义了
hardware-update-predecessor/hardware-update-successor。
tag memory effects/checked memory effects: 这两个是和memory tag相关的effect。
barrier effects: spec上写的是DSB/DMB/ISB带来的effect,其他barrier指令怎么看?
context synchronization effects(CSE effect): ISB或异常进入退出带来的effect。
branch effects: 各种branch指令带来的改变PC的effect。
TLBI effects/completed TLBI effect: tlbi指令会产生TLBI effect,tlbi后面加一个DSB.FULL
指令会产生completed TLBI effect。基于此概念,还定义了TLBI-before/TLBI-after。
fault effects, exception entry/return effects: 这块定义的比较混乱,定义关系之间
会重叠,比如异常进入退出的effect,在上面又叫CSE effect。反正按照字面意思可以看懂
就好。
TLB uncacheable effects: 把translation fault/access flag fault/address size fault
产生的effect归类为TLB uncacheable effect。基于这个概念还定义了TLB uncacheable-write-predecessor和
TLB uncacheable-write-successor。
low order bits/same low order bits/same location: 这组定义是为了定义最后的same
location,这里说的不清楚。
2.3.2
这一节定义的是单条指令内在dependency关系,像CAS/SWAP这种读写effect都有的指令,
CAS Xs, Xt, [Xn]指令中,如果Xs和Xn地址上的数据相等,就把Xt的值写到Xn地址上。
注意,2.3.2的标题是“intrinsic dependency relations”,就是这一节定义的还是”关系“,
并没有定义指令之间要准守的先后循序。
2.3.3
translation-intrinsically-before。协议里写比较模糊,加个例子比较好。
2.3.4
tag-check-intrinsically-before
2.3.5
各种dependency的定义,定义的是依赖的形式,至于基于这些依赖形式的指令先后顺序,这里
并没有定义。
dependency through registers and memory:
一个PE上,寄存器或者地址上的RAW关系。一条指令中的data dependency关系。关系可以传递。
basic dependency:
两个effect是一样的(相同observed,相同作用结果)。上述的registers/memory dependency。
address dependency:
简单理解为,对于两个memory effect的指令,后一条指令用了前一条指令的输出作为地址。
data dependency:
简单理解为,对于两个memory effect的指令,后一条指令的数据用了前一条指令的输出。
control dependency:
只是定义了控制依赖的形式,有没有序要上要求,这里没有说啊。
所以,我们可以简单总结下,对于address/data/control dependency基本上描述的是两条
memory操作指令之间的依赖关系,这些依赖关系不是前后指令直接在地址上的依赖关系。
可以看到这里和RISCV中定义的address/data/control dependency基本上是一样的。
后面pick xxx dependency中,似乎后一条指令里还有intrinsic的依赖?
2.3.6
各种order relation的定义。
CSE-ordered-before: 如上面提到的,上下文同步时的order。控制依赖里如果前一个指令
有显示memory read, 后一个指令有CSE effect,就是这种order。结合后面看,这种情况下
也是保序的。
dependency-ordered-before:
这里在定义order了,单核上的各种基本序都是这条里面定义的,注意这里的“序“指的还是
关系。“A dependency creates externally-visible order between …”,dependency创建
了order,但是这里并没有说order里元素的先后关系。
注意这里的order细化了上面的dependency,我们看control dependency相关的order,在这里
明确提出了在一个control dependency里,后面的一个是memory write。也就是这里对后一个
effect是memory read的control dependency关系是没有序上的定义的,配合后面创建先后
关系的定义,control dependency里,后面的memory read是不存在先后顺序的约束的,这个
和我们一般的认知也是相符的。
…
pick-ordered-before:
atomic-ordered-before:
DSB-ordered-before:
barrier-ordered-before:
主要讲DMB的order。
TTD-read-ordered-before:
TLBI-ordered-before:
TLBI-coherence-before:
locally-ordered-before:
这里基本上汇集了单核上的所有order的定义。
pick-locally-ordered-before:
hardware-required-ordered-before:
包含了locally-ordered-before,又汇集了如上的其他类型的order定义。
hazard-ordered-before:
应该是特殊定义的一种order?
2.3.7
External ordering constraint的定义,包含了单核上order的定义,描述中使用了“ordered-before”
的词语:“An arbitrary pair of effects is ordered”, 这里才出现ordered(被排序)的概念。
external visibility requirement:
这里external visibility requirement的描述包括了hardware-required-ordered-before,
hardware-required-ordered-before包含了单核上order的定义。
…
external completion requirement。
external global completion requirement 都展开分析下…
之前的ARM spec里有“Internal visibility requirement”的定义,里面明确有这样的语句:
“…, then M1 will be seen to occur before M2 by that Observer”,像这样的语句才是
在明确定义指令的先后关系。(2023.4.12版本的spec没有这一章节)
2.3.8
completion and endpoint ordering。
2.3.10
SVE相关的内存序定义。
2.3.11
投机执行相关的约束。
2.3.12
ARM里所有barrier指令在这一节定义。
2.3.13
limited ordering regions。就是用户可以自定义一些物理内存区域出来,这些内存区域里的
指令和load acquire/store release的定义是用户可以重新定义的。