当我的程序执行具有获取语义的加载操作/具有释放语义的存储操作或可能是全栅栏时,它会使 CPU 的缓存无效。
我的问题是:缓存的哪一部分实际上是无效的?只有保存我使用的变量的缓存行获取/释放?或者整个缓存都失效了?(L1 + L2 + L3 .. 等等?)。当我使用获取/释放语义或使用全栅栏时,这个主题有什么不同吗?
unknown
问问题
4746 次
2 回答
3
我不是这方面的专家,但我偶然发现了这份文件,也许它有帮助 http://www.rdrop.com/users/paulmck/scalability/paper/whymb.2009.04.05a.pdf
于 2010-02-07T14:57:29.953 回答
2
当您在没有围栏或互斥锁的情况下执行加载时,加载的值可能来自任何地方,即缓存、寄存器(通过编译器优化)或 RAM ......但从您的问题来看,您已经知道这一点。
在大多数互斥锁实现中,当您获得互斥锁时,始终会应用栅栏,无论是显式(例如,mfence、屏障等)还是隐式(例如,在 x86 上锁定总线的锁定前缀)。这会导致路径上所有缓存的缓存行无效。
请注意,整个缓存不会失效,只是内存位置的相应缓存行。这还包括互斥体的行(通常作为内存中的值实现)。
当然,还有特定于架构的细节,但这是它的一般工作方式。
另请注意,这不是使缓存失效的唯一原因,因为一个 CPU 上的操作可能需要另一个 CPU 上的缓存才能失效。在谷歌上搜索“缓存一致性协议”将为您提供有关此主题的大量信息。
于 2010-02-07T15:15:19.170 回答