并发原理 — CPU原子性指令(一)
本篇文章将以Intel CPU作为讨论基础
一、并发的由来
- 一台计算机有2个cpu,其中CPU1执行程序A,CPU2执行程序B,由于程序A和程序B是两个不同的应用程序,所以它们两个之间并不存在并发问题。
2.现在两个CPU要执行程序A的同一段代码,比如对变量a执行加1操作,代码a=a+1经过汇编器编译之后就是如下指令片段:addl $1,-4(%esp);
Intel CPU的指令集属于复杂指令集类型(CISC),其内部也是由微指令组成,就拿上面的加1操作指令,在CPU内部执行的时候可能会分成如下三步:
(1)从内存中取到1放入寄存器中
movl -4(%ebp),%eax
(2)对寄存器中的数执行加1操作
addl $1,%eax
(3)将加操作的结果写回内存中
movl %eax,-4(%ebp)
3.那么问题就来了:由于执行的是同一段代码,我们期望最后的结果是两个CPU各加一次,也就是a=3。但实际情况存在穿插执行:CPU1和CPU2同时执行了步骤1,此时a=1;然后CPU2执行了加法操作并把数据写入了内存,此时a=2,但CPU1已经取到的值是1,执行加法指令操作,接着把结果写入内存,结果依然是a=2。与我们预期的a=3不符,造成数据紊乱。造成数据紊乱的根本原因就是穿插执行,多个CPU操作同一个可读可写的数据就会有并发问题。那在CPU层面是如何解决并发问题呢?
二、CPU解决并发问题的方案
1.对总线上锁
为了解决并发问题,我们能想到的就是把以上三个步骤的代码当作一个整体,要么全部不执行,要么全部执行不能被穿插,我们称之为原子性代码:将一串操作定义为不能拆散的基本操作。
CPU在访存的时候需要通过控制总线、数据总线和地址总线相结合从内存读写数据,由此可以得知第一种解决办法就是对总线上锁。但这种方法有个很大的弊端,一旦锁了总线,就算其他CPU执行的不是同一个程序的代码,那么这些CPU也得等待,这将造成严重的性能损耗,锁的粒度太大,为此我们考虑如何将锁细粒度化?
2.对缓存行上锁
CPU内部有缓存,为了加速访问,CPU会把数据a相邻连续的一段内存空间数据(缓存行)加载到缓存中,为此得到了我们第二种解决数据紊乱的办法:对缓存行上锁。一旦数据a发生改变,会根据CPU的MESI协议来更新数据,达到数据一致性。[关于CPU的MESI协议可以参考本篇文章]
3.原子性指令
综上所述,intel cpu提供了原子性指令,只要指令支持lock前缀,那么它就可以把这条指令变成原语指令(原语:原子性的语义),比如 add,加上lock前缀就是 lock;add ,那么加法操作就变成了原子性操作,不会再被穿插执行了。但也有一些指令比较特殊,它们本身就是原语指令,不需要lock前缀,比如:xchg。
三、上层应用的并发解决方案
只有CPU提供了原子性指令,上层应用才能够根据这些指令来设计出指令段与指令段之间的原子性操作。这是一种自底向上的设计,没有CPU最底层的支持,上层应用根本就无法解决并发问题。应用程序使用自身语言提供的并发操作函数库,比如java的juc包,而这些函数库又会封装OS的系统调用或者使用glibc库,OS的系统调用最终会使用CPU提供的原子性指令。
并发原理 — CPU原子性指令(一)的更多相关文章
- java高并发核心要点|系列4|CPU内存指令重排序(Memory Reordering)
今天,我们来学习另一个重要的概念. CPU内存指令重排序(Memory Reordering) 什么叫重排序? 重排序的背景 我们知道现代CPU的主频越来越高,与cache的交互次数也越来越多.当CP ...
- 【Java虚拟机5】Java内存模型(硬件层面的并发优化基础知识--指令乱序问题)
前言 其实之前大家都了解过volatile,它的第一个作用是保证内存可见,第二个作用是禁止指令重排序.今天系统学习下为什么CPU会指令重排. 存储器的层次结构图 1.CPU乱序执行指令的根源 CPU读 ...
- 单片机、CPU、指令集和操作系统的关系
郑重声明:转载自http://blog.csdn.net/zhongjin616/article/details/18765301 1> 首先讨论各种单片机与操作系统的关系 说到单片机,大家第一 ...
- cpu读取指令时读取的长度
CPU读取指令时,如果单字节指令,一次访存即可完成读取操作:如果是多字节指令,会根据第一次读取指令的操作码与寻址标志位,判断指令的后续长度,进而完成整个指令的读取,同时指令指针IP会自动进行修改,指向 ...
- MySQL InnoDB 实现高并发原理
MySQL 原理篇 MySQL 索引机制 MySQL 体系结构及存储引擎 MySQL 语句执行过程详解 MySQL 执行计划详解 MySQL InnoDB 缓冲池 MySQL InnoDB 事务 My ...
- Python 之并发编程之进程上(基本概念、并行并发、cpu调度、阻塞 )
一: 进程的概念:(Process) 进程就是正在运行的程序,它是操作系统中,资源分配的最小单位. 资源分配:分配的是cpu和内存等物理资源 进程号是进程的唯一标识 同一个程序执行两次之后是两个进程 ...
- 并发编程-CPU执行volatile原理探讨-可见性与原子性的深入理解
volatile的定义 Java语言规范第3版中对volatile的定义如下:Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量.Jav ...
- CPU 多核指令 —— WFE 原理【原创】
转自:http://tinylab.org/arm-wfe/ Zhang Binghua 创作于 2020/05/19 打赏 微信公众号 知识星球 关注 @泰晓科技 与数千位一线 Linux 工程 ...
- 【多线程与高并发原理篇:4_深入理解synchronized】
1. 前言 越是简单的东西,在深入了解后发现越复杂.想起了曾在初中阶段,语文老师给我们解说<论语>的道理,顺便给我们提了一句,说老子的无为思想比较消极,学生时代不要太关注.现在有了一定的生 ...
随机推荐
- TypeScript 接口继承
1.TypeScript 接口继承 和类一样,接口也可以通过关键字 extents 相互继承.接口继承,分为:单继承和多继承,即继承多个接口.另外,接口也可以继承类,它会继承类的成员,但不包括具体的实 ...
- 难道ERP"死了",中台"凉了",低/无代码要称王了?
业内有一种说法,ERP经历了20多年的发展,其理念已经行不通,跟不上时代.后起之秀"中台"经历了崛起.走红.被传唱等阶段.并且已经冷却下来.此外,随着市场的不断变化,"低 ...
- 管正雄:基于预训练模型、智能运维的QA生成算法落地
分享嘉宾:管正雄 阿里云 高级算法工程师 出品平台:DataFunTalk 导读:面对海量的用户问题,有限的支持人员该如何高效服务好用户?智能QA生成模型给业务带来的提效以及如何高效地构建算法服务,为 ...
- 弹性布局( display: flex;)
参考: https://www.cnblogs.com/hellocd/p/10443237.html
- CentOS7添加swap分区
买了个云主机,只有1G内存,跑爬虫经常内存不足,于是只能添加swap来缓解: 1.官方推荐的swap大小定义 2.使用dd命令在根下创建swapfile dd if=/dev/zero of=/swa ...
- HashTable集合和练习题_计算一个字符串中每一个字符出现的次数
HashTable集合 /** * java.util.Hashtable<K,V>集合 implement Map<K,V>接口 * Hashtable:底层也是一个哈希表, ...
- Ubu18远程登录密匙设置
Ubu18设置远程密匙登录 相关文件 /etc/ssh/sshd_config 注意vscode使用博客园插件需要进行端口转发,在vscode端口处设置41385 本地生成密匙,任选一种,这里只介绍第 ...
- React报错之Cannot find name
正文从这开始~ .tsx扩展名 为了在React TypeScript中解决Cannot find name报错,我们需要在使用JSX文件时使用.tsx扩展名,在你的tsconfig.json文件中把 ...
- YII学习总结5(视图)
<?php namespace app\controllers; use yii\web\Controller; class HelloController extends Controller ...
- BTDetect用户手册和技术支持
BTDetect用户手册和技术支持 1. 程序主要功能 BTDetect是BT(BioTechnology) Detect 生物科技检测的缩写.本程序将根据用户的回答推断其两大基因类型.以及具体的小分 ...