网站首页 > 文章精选 正文
本篇文章将以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提供的原子性指令。
猜你喜欢
- 2025-01-21 单片机的由来及基础原理
- 2025-01-21 改变世界的马斯克
- 2025-01-21 CPU架构与指令集
- 2025-01-21 一文搞懂啥是CPU、MPU、MCU、SoC!
- 2025-01-21 头条新手写什么最简单?微头条不会写,用AI辅助写作,分分钟搞定
- 2025-01-21 「西门子指令」INC_B、INC_W、INC_DW指令应用详解
- 2025-01-21 15年大牛用140多个实战案例深入讲解Java微服务架构文档
- 2025-01-21 快速掌握S7-1200PLC与HD20变频器模拟量控制
- 2025-01-21 计算机组成原理复习要点(复习必过)
- 2025-01-21 计算机区分指令和数据有2种方法
- 05-15数据结构错题收录(十八)
- 05-15数据结构与算法——带你走进循环链表的相关操作
- 05-15二叉树展开为链表-迭代法
- 05-15江南大学商学院2017届毕业生专场招聘会成功举办
- 05-15国联证券联合华东政法大学开展大学生职业规划大赛
- 05-15新南威尔士大学2024年T3学期(9月开课)提前截止通知
- 05-15免中介服务费!留学云护航世纪大学国际教育计划
- 05-15【才o头条】上海华力2022届秋招补录启动!
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)