我找不到详细解释该策略如何工作的资料。写策略的组合在Jouppi的论文中有解释。这就是我的理解。
- cpu向cache发送写请求。
- 请求导致cache miss。 (Write-Allocate)在cache中为这个请求分配一个cache块。
- 写请求块从较低内存中取出到分配的缓存块。 现在我们可以写入由fetch分配和更新的缓存块。
CPU是否必须在缓存上重试写请求,直到write-hit发生?(在将数据块取出到分配的缓存块后)
如果没有,在此期间写请求数据在哪里被保存 ?
编辑:我想我已经在K86™处理器的写分配实现中找到了我的答案。它直接被写入分配的缓存块,并在稍后与读请求合并。
它直接被写入分配的缓存块,并稍后与读请求合并。
不,AMD的pdf不是这么说的。他们说存储数据与刚从内存中获取的数据合并,然后存储到L1缓存的数据数组中。
Cache以Cache -line粒度跟踪有效性。它无法存储"字节3到6是有效的"这一事实;当数据从内存到达时保存它们"。这种逻辑太大,无法在每一行缓存数组中复制。
还请注意,你找到的pdf描述了他们AMD的K6微架构的一些特定行为,这是单核的,一些模型只有一个级别的缓存,所以没有缓存一致性协议甚至是必要的。他们确实使用L1和L2缓存之间的MESI来描述K6-III(模型9)。
CPU写入缓存必须保留数据,直到缓存准备好接受它。不过,这不是一个重试直到成功的过程。这更像是缓存在准备接受存储时通知存储硬件(即,如果缓存与使用MESI协议的其他缓存一致,则该行处于活动状态,并且处于Modified状态)。
在一个真实的CPU中,多个未完成的失误可以同时发生(即使没有完全无序的推测执行)。这被称为miss下的miss。CPU<>缓存连接需要为每个未完成的miss提供一个可以并行支持的缓冲区来保存存储的数据。例如,一个核心可能有8个缓冲区,并支持8个未完成的加载或存储失败。在8个缓冲区中的一个可用之前,第9个内存操作无法开始发生。在此之前,数据必须留在CPU的store队列中。
这些缓冲区可以在加载和存储之间共享,或者可以有专用的存储缓冲区。OP报告说,搜索存储缓冲区发现了许多相关的感兴趣的东西;一个例子是维基百科MESI文章的这一部分。
在现代高性能设计中,L1缓存实际上是CPU核心的一部分。它与内存顺序逻辑紧密集成,并且需要能够有效地支持原子操作(如lock inc [mem]
)和许多其他复杂操作(如内存重排序)。例如,请参阅https://en.wikipedia.org/wiki/Memory_disambiguation#Avoiding_WAR_and_WAW_dependencies。
其他一些术语:
- 存储缓冲区
- 存储队列
- 内存命令缓冲区
- cache写端口/cache读端口/cache端口 全球可见
远相关:一个有趣的帖子,调查英特尔IvyBridge的L3缓存的自适应替换策略,使它在扫描一个巨大的数组时更能抵抗驱逐有价值的数据。