2

如果我有一个数据缓存行并且第一个字节正在被原子修改,我是否仍然可以同时从该缓存行读取不同字节的数据?或者我是否会尝试阅读有关正在发生的原子更新并等待它?

我试图了解上述场景的性能影响。

4

1 回答 1

2

高速缓存一致性保持在行粒度上,如今在大多数 CPU 中通常为 64B。进行修改的核心将首先请求整行的所有权,这意味着所有其他核心必须使它们的副本无效(如果它们有的话)。任何其他尝试读取的核心都必须请求该行,这将导致窥探被发送到修改核心。从那里你有两个选择:

  1. 修改核心完成读取-修改-写入序列,并且该行与最新修改的数据位于其缓存中 - 在这种情况下,窥探将启动 WB 序列,更新的行将可供所有人使用,并且第二个核心可以从中读取任何字节。

  2. 修改核心通过加载获得了线路,但它的存储仍然没有进行更改(这是可能的,因为存储通常在管道中执行得更晚,而加载通常是推测性的)。在这种情况下,核心必须保护线路不被窥探,通常通过对此类操作实施内部锁定。请注意,例如在 x86 上,大多数原子读取-修改-写入操作都需要锁定前缀。另请注意,正常的读+写(非原子)序列只会在该点丢失该行,并稍后再次获取它以供存储,从而失去连贯性。

编辑:按照 Paul 的评论,确实可以设计一个允许子行粒度跟踪的缓存系统。这基本上意味着将 MESI 协议的基本块与用于缓存的基本块大小解耦,您需要为每个子集添加状态位(但仍可以对所有子集使用单个标签),仅使本地子集无效,并最终执行以某种方式合并以重新获得全线。但是,开销会使其非常罕见,而且我不熟悉商业 CPU 这样做只是为了避免错误共享。无论哪种方式,由于这样的子块可能不是字节大小的,因此原始问题仍然适用于同一块中的字节。

于 2015-09-07T06:01:13.057 回答