目录前言1、概念2、软件模型3、Master 要完成的操作3.1 ACE Master Exclusive Load3.2 ACE Master Exclusive Store4、Interconnect 总线要完成的操作总结参考前言前两篇介绍了 ACE 一致性模型和一致性传输的原理涵盖以下内容增强信号 AC/CD/CR 的功能提供 cache line 状态维护和数据读取ARM MOESI 一致性模型一致性传输分类Initiating cache 与 Snooped cache 基于 RRESP / CRESP 的状态变化规则Interconnect 在一致性传输中需要完成的操作本篇在一致性传输的基础上进一步分析 Exclusive 读取机制的概念与硬件工作原理旨在对 ARM 协议规范中的关键要点进行系统性梳理与解读。1、概念Exclusive 读取包括读和写使用 LDREX / STREX 指令涉及 AR 通道中的三种一致性传输类型。LDREX 是 Exclusive 读使用 ReadShareWBnWA 或 WBWA或者 ReadCleanWTnWASTREX 是 Exclusive 写使用 CleanUniqueLDREX / STREX 必定成对使用但在 Interconnect 上不一定能观察到这种成对关系参见第 4 节LDREX / STREX 均使用 ACE 信号 ARLOCKExclusive 读取的最大并行度取决于 Cluster 内的 CPU 核心数量上文中出现的 WTnWA / WBWA / WBnWA 是 cache line 的读写分配策略在 MMU 页表中配置具体可参考 ARM 架构文档。ARM 内核对 LDREX / STREX 的支持还区分 security 属性安全和非安全域之间互不影响LDREX / STREX 由哪个内核发起这一信息通过 ARID 信号体现。例如一个 Cluster 包含 8 个 core则 ARID 的低三位指示对应的内核序号具体定义通常在 ARM TRM 中有详细描述。2、软件模型LDREX / STREX 指令是泛称实际上它们可操作的数据宽度可以是 8 / 16 / 32 / 64 位各有对应的具体指令下文以 32 位为例。以最常见的生产者 / 消费者模型为例发送方和接收方位于不同内核那么它们之间如何利用 Exclusive 机制实现同步呢Exclusive 的本质是发送方与接收方之间的互斥协同遵循两个步骤LOCK步骤将某个地址置为 1获取消息缓冲区的操作权限UNLOCK步骤将某个地址清为 0释放消息缓冲区的操作权限对于发送方伪代码如下while(1) { LOCK(addr); send_msg(); // 判断缓冲区有效标志若为 0填充消息并将标志置 1若为 1缓冲区还未被接收方处理执行下一步 UNLOCK UNLOCK(addr); }对于接收方伪代码如下while(1) { LOCK(addr); rcv_msg(); // 判断缓冲区有效标志若为 1处理消息并将标志清 0若为 0缓冲区无消息执行下一步 UNLOCK UNLOCK(addr); }LOCK 和 UNLOCK 的汇编实现如下LOCK: // R0: address stmfd sp!, {r3-r4, lr} check_unlock: ldrex r3, [r0] strex r4, r3, [r0] cmp r4, #0 bne check_unlock // updated by other masters, then check again cmp r3, #0 bne check_unlock // LOCK, then check again to wait UNLOCK ldrex r3, [r0] // start to LOCK ldr r3, 0x1 strex r4, r3, [r0] cmp r4, #0 bne check_unlock // updated by other masters, then check again ldmfd sp!, {r3-r4, lr} bx lr UNLOCK: // R0: address stmfd sp!, {r3-r4, lr} unlock_fail: ldrex r3, [r0] ldr r3, 0x0 strex r4, r3, [r0] cmp r4, #0 bne unlock_fail // unlock failed, try again ldmfd sp!, {r3-r4, lr} bx lr从软件视角来看LDREX / STREX 提供了一套原子操作语义。接下来我们将深入硬件层面分析监控逻辑如何支撑这一语义的实现。3、Master 要完成的操作两个不同内核对同一地址同时进行置位操作理论上存在竞争风险——例如 C0 写入后立即被 C1 覆盖。ARM 在 Core 之外、Cluster 之内设置了监控逻辑专门监测 LDREX 与 STREX 之间的写操作其工作机制如下LDREX 置位对应内核的监控标志在 LDREX 之后、STREX 之前如果发生以下任一情况则清除监控标志同一地址被其他内核通过 STREX 写入无论 WTnWA / WBnWA / WBWA同一地址被其他内核通过普通写指令写入无论 WTnWA / WBnWA / WBWA同一地址被本内核通过普通写指令写入仅在 WTnWA 模式下STREX 写入时检查该标志若标志位为 0表明此前发生了改写行为则 STREX 操作被拦截无法更新 cache 或 Main Memory需要注意第二点中的第三种情况同一地址被本内核通过普通写指令写入时若为 WBnWA / WBWA 模式则不会置位失败标志。可以这样理解若在此之后仍有 STREX最新值仍由 STREX 写入属于事后成功写入。但在 STREX 执行之前如果其他内核读取该地址的值看到的并非 STREX 将要写入的值这是否构成 Bug无论如何在实际应用中应尽量避免本内核用普通写指令操作锁地址。若因软件缺陷导致本内核以普通写指令操作锁地址则硬件应强制该 Exclusive 操作失败以保障原子性语义。3.1 ACE Master Exclusive LoadACE Master 是否会向总线发出 LDREX 或 STREX取决于 cache line 的当前状态主要有以下三种情形cache line 初始态为 UniqueLDREX 和 STREX均不会出现在总线上所有操作在 Cluster 内部完成。例如之前执行过 LDREX / STREXSTREX 产生了 Unique 状态因此第二次 LDREX / STREX 直接在 Cluster 内完成无需对外发出。唯一的例外是 WTnWA 模式因为其读写均不分配 cache line。LDREX 执行后 cache line 进入 Unique 状态此后的STREX不会出现在总线上。例如初始态为 IInvalid执行 LDREX 后收到 RRESP[3:2]2b01进入 UD 状态从外部观察仅看到 LDREX看不到 STREX。cache line 初始态为 ShareLDREX不会出现在总线上但 STREX 会向外发出。例如此前有过一次 LDREX / STREX之后其他 Master 发出 LDREX自身进入 Share 状态SD / SC此时自身再次执行 LDREXAR 请求不会穿透 Cluster 出现在总线上。上述三种情形本质上是对 Interconnect 的行为要求对于 Master 而言始终表现为 LDREX STREX ARLOCK。Master 在发出 LDREX 之后可以重新发起LDREX / STREX序列这并无特别之处本质上只是监控标志被重复置位一次。3.2 ACE Master Exclusive Store在执行 STREX 时若 cache line 处于 Share 状态且此前未被改写过则 CleanUnique 必须执行否则 CleanUnique 被拦截以避免不必要的 cache line 清除。若 cache line 处于 Unique 状态上述条件自然满足LDREX / STREX 在 Cluster 内部无条件执行。4、Interconnect 总线要完成的操作Interconnect 需要提供 POSPoint of Serialization监控逻辑确保 Initiating Master 的 STREXCleanUnique仅在其 cache line 未被其他 Master 通过 STREX 清除的前提下才能发出 AC 请求去 Snoop 其他 Master。换句话说在 FAIL 情况下不产生 AC CleanInvalid 请求同时 RRESP 返回 OKAY 响应。上述 POS 功能并非 Exclusive 机制独有而是任何一致性传输都必须具备的基础能力主要体现在 AR / R / RACK 通道的队列管理上AR 请求按顺序串行发出缓冲管理并行限制当有 AR 请求正在发送时若新的可发送请求到来新请求需放入缓冲队列冲突判断若缓冲队列中存在与当前发送的 AR 请求操作同一 cache line 的请求在前一请求完成前以收到 RLAST 为准该请求需保持在缓冲队列中当缓冲队列中同时存在多个请求时按一定优先级进行仲裁次序管理不同 ARID 之间允许乱序同一 ARID 必须保序。对不同 ID 应尽可能支持最大程度的并行同一 ARID 必须等待最早到达的请求发送完毕后才能发送后续请求。R 通道允许乱序需要队列管理RACK 通道允许乱序需要队列管理上述机制本质上也是 ROBReorder Buffer设计的基础。上述内容的核心要点如下Monitor 必须能够监控所有线程的并行执行区分 Security / Non-Security标志位总比特数为单个 Cluster 内核数 × Cluster 数量 × 2线程标志位在自身的 LDREXReadShare 或 ReadClean和STREXCleanUnique到来时置位且仅能根据 AxID 置位对应线程的标志位清除 Snooped Master 的所有线程标志位发生在 Initiating Master 发出 CleanUnique 且 STREX 成功即 cache line 内容未被其他 Master 改写的条件下Initiating Master STREX 成功时无需复位自身标志位。这一点对 Non-Sharable Monitor 是必要的但对 Sharable 而言在 Interconnect 级别并非必须——因为 STREX 成功时Initiating Master 的 cache 一定处于 Unique 状态后续 LDREX / STREX 均无条件执行除非cache line 配置为 WTnWAcache line 被其他 Master 复位上述第二点中提到 STREX 到来时需置位是因为存在一种例外情形正常的LDREX STREX组合在 Interconnect 上会表现为STREX STREX原因如下cache line 初始状态为 SCShared Clean执行 LDREX由于处于 SC 状态Interconnect 无法观测到 LDREX 的 ReadShare 或 ReadClean执行 STREX由于处于 SC 状态Interconnect 可以观测到 CleanUnique对于此 STREX不能转换为 AC CleanInvalid且必须向 Initiating Master 返回 RRESP OKAY同时置位标志位Core 判定锁未成功再次发出 LDREX由于仍为 SC 状态LDREX 依然不可见Core 再次发出 STREX由于 SC 状态Interconnect 可观测到 CleanUnique此时因步骤 3 中已置位标志位CleanInvalid 将 Snoop 其他 Master假设未出错CRRESP[1]0Interconnect 最终向 Core 返回 RRESP EXOKAY锁地址操作完成若上一步中 Snooped Master 返回 CRRESP[1]1Core 重新发起 LDREX STREX重复第 4 步直至锁地址操作成功这段内容指出在 Interconnect 内部集成地址比较器可以有效提升性能因为它能够减少 STREX 的失败概率。其原理较为直观若无地址比较器Initiating Master 的 STREX CleanUnique 会无条件复位 Snooped Master 的所有线程标记。引入地址比较器后对 cache line 改写信息的判断更加精准——仅在地址相同时才执行复位从而避免 Snooped Master 的线程标记被过度复位进而提升 Snooped Master 的 LDREX / STREX 成功率等效降低了多核之间的竞争频率。总结本文系统介绍了 ARM 架构中 Exclusive 读取机制的概念与工作原理。Exclusive 读取基于 LDREX / STREX 指令对为多核系统提供原子操作支持。文章从以下四个层面展开概念层面LDREX 使用 ReadShare / ReadClean 传输STREX 使用 CleanUnique 传输二者通过 ARLOCK 信号实现互斥访问最大并行度取决于 CPU 核心数量。软件模型以生产者-消费者模型为例展示了基于 LOCK / UNLOCK 机制实现缓冲区互斥访问的伪代码及汇编实现。硬件行为阐述了 Cluster 内部的监控逻辑包括独占访问标志的置位与清除条件以及不同缓存状态Unique / Share下的总线行为差异。互连总线要求包括请求排序与冲突处理机制以及通过地址比较器优化性能的实现思路。该机制通过硬件监控逻辑保障原子性语义为多核同步提供了坚实底层支持在实际应用中应避免对锁地址执行普通写操作。参考1. AMBA AXI and ACE Protocol SpecificationVersion D2. ARM Architecture Reference ManualVersion B