详细解释axi协议中提到的内存类型Write-back Read-allocate
好的,我们来深入解析 AXI 协议中 Write-Back Read-Allocate 这一内存属性。这是一种极其常见且高性能的策略组合,广泛应用于现代处理器架构中,用于优化典型的工作负载。
核心结论先行
- 是什么:
Write-Back Read-Allocate是一种缓存策略组合。Write-Back: 写入操作只更新缓存,并将缓存行标记为“脏”。数据只在缓存行被替换时才写回主内存。Read-Allocate: 仅在读未命中时分配缓存行。写未命中时不会分配缓存行。
- 目标: 针对 “读多写少” 或 “写入的数据很可能被再次读取” 的工作负载。它通过最大化缓存命中率来提升性能,同时通过减少不必要的内存写入来节省带宽和功耗。
- 本质: “为读取加速,为写入省流”。这是一种在性能和效率之间取得绝佳平衡的策略。
深入解析:行为模式
让我们通过具体场景来理解这个组合的行为:
1. 读操作 (Read)
-
场景一:读命中
- 数据在缓存中。
- 直接从缓存返回数据给处理器。
- 速度极快。
-
场景二:读未命中 - Read-Allocate 策略的核心应用
- 数据不在缓存中。
- Read-Allocate 策略生效: 在缓存中分配一个空白的缓存行。
- 发起 AXI 总线读事务,从主内存读取整个缓存行的数据。
- 将数据填充到缓存行中。
- 返回处理器所请求的数据。
- 结果: 该数据及其相邻数据被加载到缓存中,为后续的访问(很可能具有空间局部性)提供了加速潜力。
2. 写操作 (Write)
-
场景一:写命中
- 要写入的地址已经在缓存中(很可能是因为之前被读取过)。
- Write-Back 策略生效: 处理器只更新缓存中的数据,并将其标记为 “脏”。
- 不会立即发起 AXI 写事务到内存。
- 结果: 写入速度极快,且消耗的总线带宽为零。
-
场景二:写未命中 - 这是与 Write-Allocate 的关键区别
- 要写入的地址不在缓存中。
- Read-Allocate 的“另一面”生效(即 No Write-Allocate): 不会为这个新地址分配缓存行。
- 数据通过 AXI 总线直接写入主内存。
- 结果: 写入完成,内存已更新。缓存内容无任何变化。
为什么需要这种策略?—— 设计动机与应用场景
这种策略是基于对典型程序行为(如访存局部性原理)的深刻洞察而设计的。
-
程序代码段 (Text Segment):
- 特点: 代码是只读的,或者绝大部分时间是被读取的(取指)。极少有写入操作。
- 为什么用它:
Read-Allocate: 当一段代码第一次被执行时(读未命中),它会被加载到缓存中,后续无数次执行都会命中缓存,速度极快。Write-Back: 即使有极少数情况需要修改代码(如动态链接库加载、JIT编译),一旦代码在缓存中,写入操作也会非常快。
-
频繁读取的共享数据:
- 特点: 一个在多核间共享的配置结构、查找表或常量数据。多个核心会频繁读取它,但很少写入。
- 为什么用它:
Read-Allocate: 第一个读取它的核心会将其载入自己的缓存。后续其他核心读取时,可以通过缓存一致性协议(如MESI)从第一个核心的缓存中共享该数据,速度远快于从内存读取。Write-Back: 偶尔的写入操作会在缓存中快速完成。
-
写入后立即读取的数据结构:
- 特点: 一个生产者-消费者队列。生产者核心写入数据,消费者核心读取数据。但通常,生产者核心在写入后,很快就会由消费者核心来读取。
- 为什么用它:
- 生产者核心的写入如果是未命中,会直接写内存(
No Write-Allocate)。 - 消费者核心的读取会发生读未命中,从而触发
Read-Allocate,将生产者写入的数据整个缓存行加载到自己的缓存中。这不仅读到了目标数据,还预取了相邻数据,优化了后续操作。
- 生产者核心的写入如果是未命中,会直接写内存(
-
节省带宽和功耗:
Write-Back策略避免了每次写入都访问内存,大大减少了总线活动和内存访问次数,这在移动设备和数据中心中对于降低功耗至关重要。
对比:为什么不用 Write-Allocate?
Write-Allocate 在写未命中时加载整个缓存行,对于“只写一次”的数据来说,这是一种浪费。它加载了可能无用的数据,污染了缓存,并消耗了额外的读带宽。
Read-Allocate 则更聪明:它假设如果一块数据连被读取的“资格”都没有,那也不值得为它的写入而分配宝贵的缓存空间。数据必须首先通过被读取来“证明”自己的价值,才有资格被缓存。
在 AXI 协议中的表示
在 AXI 协议中,这是通过 ARCACHE 和 AWCACHE 信号实现的。
-
对于读事务 (
ARCACHE):ARCACHE[1](C) = 1 (Cacheable)ARCACHE[2](RA) = 1 (Read-Allocate) <- 这是核心- 一个典型的读配置是
ARCACHE = 4'bxx1x(例如4'b1010)。
-
对于写事务 (
AWCACHE):AWCACHE[1](C) = 1 (Cacheable)AWCACHE[3](WA) = 0 (No Write-Allocate) <- 这是关键区别AWCACHE[0](B) = 1 (Bufferable) (对于 Write-Back,此位为1,表示写入操作可以被处理器内部的写缓冲区管理)- 一个典型的写配置是
AWCACHE = 4'b1011。
对比总结
| 特性 | Write-Back Read-Allocate | Write-Back Write-Allocate | Write-Through Read-Allocate |
|---|---|---|---|
| 读未命中 | 分配缓存行 | 分配缓存行 | 分配缓存行 |
| 写未命中 | 不分配,直写内存 | 分配缓存行,只写缓存 | 不分配,直写内存 |
| 写命中 | 只写缓存(快) | 只写缓存(快) | 写缓存和内存(慢) |
| 优点 | 避免“只写”数据污染缓存,带宽效率高 | 写入性能极佳 | 数据强一致 |
| 缺点 | 偶尔的“写后读”可能性能不佳 | 易造成缓存污染 | 写入性能差,带宽开销大 |
| 适用场景 | 通用程序执行(代码、读多写少数据) | 频繁写入的私有数据 | 读多写少的共享数据 |
总结
Write-Back Read-Allocate 是现代处理器架构中最主流、最均衡的缓存策略。
- 它的设计哲学: “不见读,不缓存”。数据必须通过被读取来证明其价值,才有资格占用昂贵的缓存空间。而对于写入,则采用“懒惰”策略,批量写回,以最大化效率和性能。
- 它的核心价值: 完美契合了大多数应用程序的“读多写少” 的访存特征,在高性能、低带宽消耗和低功耗之间取得了最佳平衡。
- 它的普遍性: 你个人电脑、手机里的 CPU,其默认的内存访问模式几乎都是这种策略。它是让现代计算得以高效运行的无声功臣之一。
浙公网安备 33010602011771号