本文转载自聊聊CPU的LOCK指令

导语

在多线程操作中,可能最经常被提起的就是数据的可见性、原子性、有序性。不管是硬件方面、软件方面都在这三方面做了很足的工作,才能保证程序的正常运行。

之前发表过一篇文章聊聊缓存一致性协议 如果感兴趣的话可以去阅读一下,里面谈到了缓存一致性的实现和处理过程,读完之后可以仔细去细想一下缓存一致性协议到底解决了什么问题。个人理解缓存一致性协议解决了CPU层面的可见性和一致性问题,阅读到这里可以在这里停下来,仔细回想一下缓存一致性的原理,它通过监听共享总线上消息,对自己缓存中的数据修改不同的状态,来保证数据的一致性,对自己缓存中的数据失效后,下次读取会从主存中直接读取最新的数据 ,可以保证可见性,同时保证各缓存中的数据是一致的。

软件的并发编程一样,其实除了可见性、有序性,在计算机指令在执行的过程中,CPU通过不停地切换线程执行,给每个线程分配CPU时间片来实现多线程机制,一定也会存在原子性问题,在计算机层面是怎么解决原子性问题的,这就我们今天要聊的LOCK#指令,有时也被我们称为总线锁。

LOCK指令作用

Intel 64 and IA-32 Architectures Software Developer’s Manual 中的章节LOCK—Assert LOCK# Signal Prefix 中给出LOCK指令的详细解释

大至翻译之后的意思如下

在CPU的LOCK信号被声明之后,在此期随同执行的指令会转换成原子指令。在多处理器环境中,LOCK信号确保,在此信号被声明之后,处理器独占使用任何共享内存。

在不大多数IA-32和Inter64位处理器中,锁可能在没有LOCK#信号的时情况下发生。请参阅下面的“IA32体系结构兼容性”部分的详细内容。

LOCK前缀只能预加在以下指令前面,并且只能加在这些形式的指令前面,其中目标操作数是内存操作数:add、adc、and、btc、btr、bts、cmpxchg、cmpxch8b,cmpxchg16b,dec,inc,neg,not,or,sbb,sub,xor,xaddxchg

如果LOCK前缀用上述列表中的指令并且源操作数是内存操作数(也就是指令没有对内存进行写操作),可能会出现未定义的操作码异常(ud)。

如果锁前缀与任何不在上面列表中的指令一起使用,也将生成未定义的操作码异常。

xchg指令不管有没有声明LOCK前缀,总是会声明LOCK信号。

锁定前缀通常与BTS指令一起使用,在共享内存环境中,以对内存地址执行读-修改-写操作。

锁定前缀的完整性不受内存字段对齐的影响。对于任意未对齐的字段,可以观察到内存锁定。

此指令的操作在非64位模式和64位模式下是相同的。

从P6系列处理器开始,当使用 LOCK 指令访问的内存已经被处理器加载到缓存中时,LOCK# 信号通常不会断言。取而代之的是,只锁定处理器的缓存。在这里处理器的缓存一致性机制确保对内存进行的操作是原子性的。请参见“锁定操作对内部处理器缓存的影响”,在Intel64和IA-32体系结构软件开发人员手册第3A卷第8章中,有关锁定缓存的详细信息。

大致翻译差不多如上,核心意思主要说明LOCK指令在声明之后通过锁定总线,独占共享内存,通过一种排它的思想确保当前对内存操作的只有一个线程,然后确定在这段声明期间指令执行不会被打断,来保证其原子性。

处理器如何实现原子操作

首先处理器会保证基本的内存操作的原子性,比如从内存读取或者写入一个字节是原子的,但对于读-改-写、或者是其它复杂的内存操作是不能保证其原子性的,又比如跨总线宽度跨多个缓存行夸页表的访问,这时候需要处理器提供总线锁缓存锁两个机制来保证复杂的内存操作原子性

总线锁

LOCK#信号就是我们经常说到的总线锁,处理器使用LOCK#信号达到锁定总线,来解决原子性问题,当一个处理器往总线上输出LOCK#信号时,其它处理器的请求将被阻塞,此时该处理器此时独占共享内存。

总线锁这种做法锁定的范围太大了,导致CPU利用率急剧下降,因为使用LOCK#是把CPU和内存之间的通信锁住了,这使得锁定时期间,其它处理器不能操作其内存地址的数据 ,所以总线锁的开销比较大。

缓存锁

如果访问的内存区域已经缓存在处理器的缓存行中,P6系统和之后系列的处理器则不会声明LOCK#信号,它会对CPU的缓存中的缓存行进行锁定,在锁定期间,其它 CPU 不能同时缓存此数据,在修改之后,通过缓存一致性协议来保证修改的原子性,这个操作被称为“缓存锁”

什么情况下使用总线锁(LOCK#)

当操作的数据不能被缓存在处理器内部,或操作的数据跨多个缓存行时,也会使用总线锁

因为从P6系列处理器开始才有缓存锁,所以对于早些处理器是不支持缓存锁定的,也会使用总线锁

有些指令自带总线锁

BTS、BTR、BTC 、XADD、CMPXCHG、ADD、OR等,这些指令操作的内存区域就会加锁,导致其它处理器不能同时访问它。

在上面指令中的CMPXCHG就是JAVA里面CAS底层常用的指令,这个指令在执行的时候,会自动加总线锁保,导致其它 处理器不能同时访问,证其原子性。

LOCK#作用总结

  1. 锁总线,其它CPU对内存的读写请求都会被阻塞,直到锁释放,因为锁总线的开销比较大,后来的处理器都采用锁缓存替代锁总线,在无法使用缓存锁的时候会降级使用总线锁
  2. lock期间的写操作会回写已修改的数据到主内存,同时通过缓存一致性协议让其它CPU相关缓存行失效

写在最后

总线锁缓存锁可以保证原子性缓存一致性协议可以保证可见性,那么JAVA中的内存模型,它做了些什么?下一篇聊聊JAVA中的内存模型(JMM)聊聊JMM

聊聊CPU的LOCK指令的更多相关文章

  1. 【操作系统之十一】任务队列、CPU Load、指令乱序、指令屏障

    一.CPU Loadcpu load是对使用或者等待cpu进程的统计(数量的累加):每一个使用(running)或者等待(runnable)CPU的进程,都会使load值+1;每一个结束的进程,都会使 ...

  2. 关于缓存一致性协议、MESI、StoreBuffer、InvalidateQueue、内存屏障、Lock指令和JMM的那点事

    前言 事情是这样的,一位读者看了我的一篇文章,不认同我文章里面的观点,于是有了下面的交流. 可能是我发的那个狗头的表情,让这位读者认为我不尊重他.于是,这位读者一气之下把我删掉了,在删好友之前,还叫我 ...

  3. 深入设计电子计算器(一)——CPU框架及指令集设计

    版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/8278418.html 作者:窗户 Q ...

  4. 使用logisim搭建单周期CPU与添加指令

    使用logisim搭建单周期CPU与添加指令 搭建 总设计 借用高老板的图,我们只需要分别做出PC.NPC.IM.RF.EXT.ALU.DM.Controller模块即可,再按图连线,最后进行控制信号 ...

  5. CPU结构与指令执行过程简介

    CPU(Central Processing Unit)是计算机中进行算术和逻辑计算处理指令的主要部件. CPU结构 CPU由通用寄存器组,运算器,控制器和数据通路等部件组成. 寄存器包括 数据寄存器 ...

  6. CPU流水线与指令乱序执行

    青蛙见了蜈蚣,好奇地问:"蜈蚣大哥,我很好奇,你那么多条腿,走路的时候先迈哪一条啊?" 蜈蚣听后说:"青蛙老弟,我一直就这么走路,从没想过先迈哪一条腿,等我想一想再回答你 ...

  7. 使用CPU的AVX指令

    arch:AVX 很抱歉GCC还不行……有……倒是 但是不是这么写的 我忘记了……官网上有 http://www.oschina.net/news/66980/kreogist-0-9

  8. java并发编程知识点备忘

    最近有在回顾这方面的知识,稍微进行一些整理和归纳防止看了就忘记. 会随着进度不断更新内容,比较零散但尽量做的覆盖广一点. 如有错误烦请指正~ java线程状态图 线程活跃性问题 死锁 饥饿 活锁 饥饿 ...

  9. 并发编程之 Java 内存模型 + volatile 关键字 + Happen-Before 规则

    前言 楼主这个标题其实有一种作死的味道,为什么呢,这三个东西其实可以分开为三篇文章来写,但是,楼主认为这三个东西又都是高度相关的,应当在一个知识点中.在一次学习中去理解这些东西.才能更好的理解 Jav ...

随机推荐

  1. 八:SpringBoot-集成JPA持久层框架,简化数据库操作

    SpringBoot-集成JPA持久层框架,简化数据库操作 1.JPA框架简介 1.1 JPA与Hibernate的关系: 2.SpringBoot整合JPA Spring Data JPA概述: S ...

  2. Java中String对象创建机制详解()

    一String 使用 private final char value来实现字符串存储 二Java中String的创建方法四种 三在深入了解String创建机制之前要先了解一个重要概念常量池Const ...

  3. 项目Js源码整合

    整合一下目前做的项目中JS中用到的相关源码等,留待记录和使用. 一.ajaxgrid源码部分 1.初始化 2.查询 3.删除 4.保存 5.根据id获取值,时间值等 6.详情.跳转链接 : a 标签 ...

  4. Cisco的互联网络操作系统IOS和安全设备管理器SDM__管理Cisco互联网络

    1.如果不能远程登录到一台设备上,可能是由于远程设备上没有设置口令.也可能是由于访问控制列表过滤了远程登录会话. show users:检查都有哪些设备连接到了此路由器. clear line #:清 ...

  5. TZOJ6556: 嗅探器

    最近在练Tarjan,看到这道题目分类在割点里面就想尝试做一下,点开发现题目数据范围竟然如此之小,算了,bfs暴力一发. 题目意思就是你需要找到一个关键节点,也可以理解成,行军打仗时必需经过的地方,敌 ...

  6. C++typename的由来和用法

  7. ProBuilder快速原型开发技术 ---操作基础

    本篇文章笔者对ProBuilder(以下简称:PB),进行操作基础的介绍. 一:PB大小图标显示方式 PB操作面板有两种显示方式:小图标与大图标.大图标优点是显示清晰操作方便,缺点是没有更加精确的参数 ...

  8. 2020牛客暑期多校训练营 (第二场) All with Pairs

    传送门:All with Pairs 题意:给你n个字符串,求出,f(si,sj)的意思是字符串 si 的前缀和字符串 sj 后缀最长相等部分. 题解:先对所有的字符串后缀hash,用map记录每个h ...

  9. P1387 最大正方形 && P1736 创意吃鱼法(DP)

    题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m ...

  10. 牛客算法周周练20 F.紫魔法师 (二分图染色)

    题意:给你一张图,对其染色,使得相连的点的颜色两两不同求,最少使用多少种颜色. 题解:首先,若\(n=1\),只需要一种.然后我们再去判断是否是二分图,对于二分图,两种颜色就够了,若不是二分图,也就是 ...