無名

大猫咪与小狮子

导航

lock cmpxchg

文章中内容有误,根据intel手册,没有发现 cmpxchg指令会有总线锁

cmpxchg 指令都会锁总线,

那么,为什么要加lock 前缀呢?

LOCK#前缀不会占用额外的字节,而是作为指令的一部分。它会被编码为一个特定的操作码前缀,告知处理器在执行指令期间锁定总线或等效连接

因为:

  1. 对于cmpxchg 总线锁而言

当处理器执行cmpxchg指令并锁定总线时,它会保持对总线的锁定,直到指令执行完成并释放总线锁。从这个意义上说,锁定总线的时间应该是指令执行的时间
因为这个时间非常短,而在其它处理器上已经正在执行的指令可能更复杂的计算和内存访问操作,所以该指令的执行可能会掩盖锁定总线的时间,而此时该指令可能会操作cmpxchg指令操作的内存区域。
使用lock前缀可以解决该问题,

inter手册描述

Intel 64和IA-32处理器提供了一个在某些内关键内存操作期间可自动断定lock#信号,用于去锁定系统总线或等效构件。当这个lock#信号被声明/断言时,来自其他处理器或总线代理的总线控制请求会被阻塞。

个人感觉,它好像也会block指定的内存地址总线

2.即使每个处理器在执行cmpxchg指令时都锁定了总线,但是在多处理器环境中,处理器的缓存可能会导致数据不一致性的问题。

当使用lock前缀,如果操作的内存已经在某个内核的缓存中,那么cpu会lock cache,同时以该内核执行指令

xchg默认会加上 lock前缀


x86中,有些指令是自带 lock 语义的,比如 XCHG;另外一些指令可以手动加上lock前缀来实现lock语义,比如BTS, BTR,CMPXCHG指令。在这些指令中,最核心的是 CAS(Compare And Swap) 指令,它是实现各种锁语义的核心指令。不同于自带原子语义的XCHG,CAS操作要通过"lock CMPXCHG"这样的形式来实现。一般而言,原子操作的数据长度不会超过8个字节。简单来说,自旋锁和读写锁的核心都是利用原子指令来CAS操纵一个32位/64位的值

需要参考的文章:
https://mp.weixin.qq.com/s/WeKM58WF6hVaxT3vRuQ2zg

posted on 2023-12-08 14:51  xiezhengcai  阅读(294)  评论(0编辑  收藏  举报