线程安全之重排序

重排序

一个处理器上面执行的多种操作,在其他处理器看来与该处理器上面程序指定的操作顺序不同
重排序是处理器,编译器,存储子系统为了改善程序执行性能而对内存访问操作执行的操作,它可以在不影响程序(单线程下)正确执行的条件改善程序执行性能
分类:
  • 指令重排序
  • 存储子系统重排序(内存重排序)
一些与重排序相关的概念
  • 源代码顺序:源代码中所指定的内存访问操作
  • 程序顺序:给定处理器中目标代码的执行顺序
  • 执行顺序:处理器中代码的真正执行顺序
  • 感知顺序:给定的处理器感知到的该处理器和其他处理器的内存访问操作

指令重排序

源代码顺序与程序顺序不同,或者程序顺序与执行顺序不同的时候我们称发生了指令重排序。指令重排序是一种动作,它是编译器,处理器对指令的顺序进行了调整
编译器对指令重排序----》java为例
java中有javac(静态编译器)和JIT(动态编译器 just in time) ,其中 javac 是将 .java 文件编译为 字节码(.class)文件,而JIT 是将字节码文件编译为宿主机器上面的机器码。javac几乎不对指令重排序,而JIT会在其任务不影响程序正确执行的情况下对源代码顺序进行调整 -----< 造成源代码顺序和程序顺序不同.
处理器重排序
现代处理器为提高程序的执行效率,会对指令进行乱序执行。即在指令按照程序指定的顺序被写入处理器,但是按顺序写入并不一定会按顺序执行,哪一条指定准备好(例如执行该指令所需要的操作数准备好)就会先执行哪一条。指令执行的结果会先写入重排序缓冲器,重排序缓冲器会将结果按照指令写入处理器的顺序排序,然后写入主内存
现代处理器乱序执行还采用了另一个策略:猜测执行。例如对于一个if语句,处理器有可能先执行if方法体内的指令,而不管if中的条件是否成立,然后检查条件是否成立,如果条件成立则将方法体内的指令执行结果写入缓存,否则抛弃

存储子系统重排序(内存重排序)

前置知识
存储子系统:写缓存器和高速缓存器
因为cpu执行指令的速度要远快于指令从主存中的读取速度,所以cpu并不是直接访问主存而是访问高速缓存,高速缓存中存放着cpu可能用到的数据与指令,和cpu要写入主存中的数据,而高速缓存又分为一级,二级,三级。现代处理器在这个基础上面还引入了写缓存器来提高写入数据到高速缓存的速度。
存储子系统重排序
存储子系统重排序是对指令执行结果的重排序,例如 俩个指令 S1和S2在被处理器执行完成后,结果被按照 s1 s2的顺序写入写缓存器中,但是写缓存器为提高性能,并不一定会按照结果写入写缓存器的顺序将结果写高速缓存。它并不会保证 first in first out,即比较晚写入写缓存器的s2 有可能 被先写入 高速缓存

重排序的规则
重排序并非没有规则的对指令,指令结果进行重新排序。它会按照一定的规则在不影响程序的正确执行下对指令和操作结果进行提高执行效率的重排序
  • 对于存在依赖关系,例如 (1) int y=2 ;(2) x=y+1; 因为 (2) 的执行依赖于 (1) 所以 (1)(2)的执行不会被重排序.
  • 存在控制依赖关系的指令可能会被重排序,例如处理器的猜测执行
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值