互斥锁的解锁/加锁操作如何比内存读取更快?
在一台典型的PC上运行x86 CPU,Intel的CPU可以完全在缓存中执行锁定操作:
如果在LOCK操作期间被锁定的内存区域被作为写回内存存储在执行LOCK操作的处理器的缓存中,并且完全包含在一个缓存行中,那么处理器可能不会在总线上断言LOCK#信号。
相反,它会在内部修改内存位置,并允许其缓存一致性机制确保操作被原子地执行。
这个操作被称为“缓存锁定”。
缓存一致性机制自动防止缓存了相同内存区域的两个或多个处理器同时修改该区域的数据。
缓存一致性机制是MESI协议的一种变种。
根据该协议,在CPU写入缓存的位置之前,它必须将相应的缓存行置于独占(E)状态。
这意味着一次只有一个CPU将给定的内存位置置于脏状态。
当其他CPU想要读取相同的位置时,所有者CPU将延迟这些读取,直到原子操作完成。
然后它遵循一致性协议,将该行进行转发、无效化或写回。
在上述情况下,锁定操作可以比未缓存的加载更快。
然而,这些时间有些过时,而且肯定过时了。
它们的目的是给出典型操作的顺序和数量级。
L1命中的时间有点奇怪,它不比典型的指令执行更快(单个数字无法描述指令执行)。
Intel优化手册报告了一个旧的CPU(如Sandy Bridge)的L1访问时间为4个周期,而有很多指令的延迟为4个周期或更少。
我会带着一颗谨慎的心态对待这些数字,避免对它们进行过多的推理。
Norvig试图教给我们的教训是:硬件是分层的,离CPU越近(从拓扑的角度来看),速度越快。
因此,在解析文件时,程序员应该避免来回移动数据到文件中,而是应该尽量减少IO压力。
当处理数组时,局部性将提高性能。
但请注意,这些技术上来说是微观优化,而且这个问题并不像看起来那么简单。
1. 一般来说,将硬件分为以下几个部分:核心内部(寄存器)、CPU内部(缓存,可能不包括LLC)、插槽内部(GPU,LLC)、专用总线设备后面(内存,其他CPU)、一个通用总线后面(PCIe - 内部设备,如网络卡)、两个或多个总线后面(USB设备、磁盘)以及完全另一台计算机(服务器)。(根据来源中的注释1)