概述
系列文章目录
多核cpu怎么保证数据一致性(一)为什么要做指令重排序?
多核cpu怎么保证数据一致性(二)cpu为什么要用高速缓存?L1,L2,L3 cache
多核cpu怎么保证数据一致性(三)MESI缓存一致性协议
多核cpu怎么保证数据一致性(四)volatile关键字、happens-before原则、内存屏障
文章目录
- 系列文章目录
- 前言
- 一、什么是指令重排序
- 1、示例1-1:
- 二、为什么要做指令重排序
- 三、重排序的原则
- 总结
前言
其实一直想写一篇关于cpu的指令运算与java代码相结合的文章,今天,它来了,本文主要介绍java的指令怎么在最高的运用电脑cpu性能的情况下保证正确的执行,会涉及到指令重排序、happens-before、内存屏障等知识点,由于知识点较多,会分为几篇文章去讲
一、什么是指令重排序
1、示例1-1:
int a = 1;
int b = 2;
a=a+1;
b=b+1;
可能会被优化成如下顺序:
int a = 1;
a=a+1;
int b = 2;
b=b+1;
我们会发现指令的顺序变了,但是执行结果不会变。
二、为什么要做指令重排序
其实做指令重排序的目的,你肯定猜得到肯定是为提升性能么。
但是具体的原理是什么呢?
其实这跟cpu相关,在cpu中,处理一个指令,例如“b=a+1”,是包含一系列工序的,如下所示:
流程就是:把数据取出放到寄存器上->执行指令->把结果存下来
这里面有十几个流程,而cpu呢,同一时间只能执行一个流程,无法并发执行,举例如下:
a=a+1;
b=b+1;
单个cpu在取a的值的时候,无法并行取b的值,在a的取指指令完成,执行下一步“执行”指令的时候,才能去取b的值,就是cpu同一时间只能执行一道工序,无法并发执行。
此时你可能想把“a=a+1”执行完了,再执行"b=b+1"不就行了么,如果这样的话,一个执行执行要花十几道工序,在执行其中一道工序的时候,其他工序都空着,是很浪费的,其实在a的取指指令执行完成,就可以执行b的取指指令了(注意:现在cpu一个取指都会分3-4道工序,其实取指的第一道工序执行完进入第二道工序,就可以执行下一条指令的第一道工序了,这里为了方便你的理解,所以做了简化说明,我认为理解到这个程度就够了,说明你已经理解了原理,在深入也没有必要)。
上面的例子中,最大化地利用了cpu,但是你看看下面这个问题,还能不能按照上面说的原理进行呢?
a=a+1;
x = a+2;
b=b+1;
此时“x=a+2”,下条指令的参数用到了上条指令的结果,这时候就要等到第一条指令完全执行完才能执行第二条了吧。否则a=a+1的结果没出来啊。此时你发现"b=b+1",这第三条指令跟前面没有关系啊,那是不是可以先执行第三条呢,否则,cpu一直空着,这多么浪费资源啊。对,这样就产生了指令重排序。
三、重排序的原则
上面我们说了指令重排序,那么指令重排序一定要有一定的原则吧:
核心原则就是:不管怎么进行指令重排序,单线程内程序的执行结果不能被改变。
在java中还有一个happens-before原则,下一节,我们就聊聊happens-before原则和其实现原理
总结
我们在上文中,用代码示例展示了
- 什么是重排序,
就是把指令不按照代码看上去的顺序执行,但是对结果没有影响 - 为什么要做指令重排序:为了提升cpu的性能和利用率
- 重排序的基本原则:不管怎么进行指令重排序,单线程内程序的执行结果不能被改变。
其实我一直认为,工欲善其事,必先利其器,在工具的使用上,我准备了专栏《java开发工具》,如果你感兴趣可以来看看
最后
以上就是温暖歌曲为你收集整理的多核cpu怎么保证数据一致性(一)为什么要做指令重排序?系列文章目录前言一、什么是指令重排序二、为什么要做指令重排序三、重排序的原则总结的全部内容,希望文章能够帮你解决多核cpu怎么保证数据一致性(一)为什么要做指令重排序?系列文章目录前言一、什么是指令重排序二、为什么要做指令重排序三、重排序的原则总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复