在我的理解中,原子操作(例如c++ atomic)首先锁定缓存行,然后执行原子操作。我有两个问题:1. 如果我们说原子比较和交换本身在硬件中是原子操作,为什么我们需要锁定缓存行和 2. 当缓存行被锁定时另一个 cpu 如何等待它?它使用自旋锁式等待吗?
谢谢
最佳答案
首先:这取决于!
1.) 如果系统锁定缓存行与 c++ 无关。这是一个缓存如何组织的问题,尤其是汇编程序指令如何与缓存一起使用。这是cpu架构的问题!
2.) 编译器如何执行原子操作取决于实现。将生成哪些汇编程序指令来执行原子操作可能因编译器而异,甚至在不同版本上也不同。
3.) 据我所知,如果无法对访问相同缓存行的其他内核执行“更聪明”的通知/同步,则完全锁定缓存行只是后备解决方案。但是通常不仅仅涉及单个缓存。想想多级缓存架构。有些缓存只对单个内核可见!因此,需要执行更多的内存系统操作,如锁定一行。如果涉及多个内核,您还必须从不同的缓存级别移动数据!
4.) 从c++的角度来看,原子操作不仅仅是一个单一的操作。真正会发生什么取决于原子操作的内存排序选项。由于原子操作经常用于线程间同步,因此对于单个原子 RMW 操作必须做更多的事情!要了解所有必须完成的工作,您应该给出 https://www.cplusplusconcurrencyinaction.com/一个机会。它详细介绍了内存屏障和内存排序。
5.) 锁定缓存行(如果真的发生了)不应该导致其他内核上出现自旋锁或其他问题,因为访问缓存行本身只需要一些时钟周期。根据架构,它只是简单地“持有”另一个核心一些周期。 “ sleep ”核心可能会在不同的管道中并行执行其他操作。但是,嘿,这是非常特定于硬件的。
正如已经给出的评论:看看 https://fgiesen.wordpress.com/2014/08/18/atomics-and-contention/ ,它给出了缓存一致性和锁定会发生什么的一些提示。
不仅仅是在引擎盖下锁定。我相信您的问题只是表面上的问题!
实际使用:别想了!编译器供应商和 cpu 架构师做得很好。作为程序员,您应该衡量您的代码性能。从我的角度来看:无需考虑如果缓存行被锁定会发生什么。您必须编写良好的算法并考虑程序数据的良好内存组织以及线程之间较少的相互关系。
关于c++ - 为什么原子操作需要独占缓存访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55075685/