在Intel® 64 and IA-32 Architectures Software Developer's Manual中的章节LOCK-Assert LOCK$ Signal Prefix中给出LOCK指令的详细解释
LOCK是一个指令前缀,也就是说LOCK会使紧跟在其后面的指令变成原子指令(atomic instruction)。
LOCK指令前缀只能加在以下这些指令前面
ADD,ADC,AND,BTC,BTR,BTS,CMPXCHG,CMPXCH8B,CMPXCHG16B,DEC,INC,NEG,NOT,OR,SBB,SUB,XOR,XADD,XCHG
总线锁
在多处理器环境中,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线LOCK,如果汇编语言的程序中在一条指令前面加上前缀“LOCK”,经过汇编以后的机器代码就是CPU在执行这条指令的时候把引线LOCK的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。
总线锁这种做法锁定的范围太大了,导致CPU利用率急剧下降,因为使用LOCK#是把CPU和内存之间的通信锁住了,这使得锁定期间其他处理器不能操作其内存地址的数据,所以总线锁的开销比较大
缓存锁
从P6系列处理器开始,如果访问的内存区域已经缓存在处理器的缓存行中,LOCK#信号不会被发送。它会对CPU缓存中的缓存行进行锁定,在锁定期间,其他CPU不能同时缓存此数据。在修改之后通过缓存一致性协议来保证修改的原子性。这个操作被称为“缓存锁”
什么情况下使用总线锁
当操作的数据不能被缓存在处理器内部,或操作的数据跨多个缓存行时,也会使用总线锁
因为从P6系列处理器开始才有缓存锁,所以对于早些处理器是不支持缓存锁定的,也会使用总线锁
网友评论