指令重排问题

4 篇文章 0 订阅
2 篇文章 0 订阅

1编译器重排序
2指令
就有点类似于t1线程中a=1的修改结果对t2线程不可见;

问题:
1重排序会带来可见性问题,所以在多线程开发中必须要关注并规避重排序。
2编译器对上下文分析然后进行优化减少对内存的交互,第一阶段,编译器重排序,就是在编译过程中,编译器根据上下文分析对指令进行重排序,
目的是减少CPU和内存的交互,重排序之后尽可能保证CPU从寄存器或缓存行中读取数据。 什么是寄存器:它们可用来暂存指令、数据和位址;
寄存器拥有非常高的读写速度,所以在寄存器之间的数据传送非常快。任意寄存器可以作为数据、结构或数组的指针;
在前面分析JIT优化中提到的循环表达式外提(Loop Expression Hoisting)就是编译器层面的重排序,从CPU层面来说,避免了处理器每次都去内存中加载stop,减少了处理器和内存的交互开销
处理器重排序,处理器重排序分为两个部分。
3并行指令集重排序,这是处理器优化的一种,处理器可以改变指令的执行顺序。
4内存系统重排序,这是处理器引入Store Buffer缓冲区延时写入产生的指令执行顺序不一致的问题。
jit指的是动态编译
与之对应的是静态编译也就是ahead-of-time compilation
某段代码第一次将要执行时被编译,jit又叫及时编译;
adaptive dynamic compilation 比及时编译较迟(自适应动态编译)
 
 在部分商用虚拟机中(如HotSpot),Java程序最初是通过解释器(Interpreter)进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁时,
 就会把这些代码认定为“热点代码”。为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码,
 并进行各种层次的优化,完成这个任务的编译器称为即时编译器(Just In Time Compiler,下文统称JIT编译器)。
 部分商用的jvm中,java程序最初是经过解释器进行执行的 interpreter 当虚拟机发现一些代码执行比较频繁的时候就把这些代码标注为热点代码;虚拟机将热点代码
 编译成和本地平台相关的机器码,并进行各种层次的优化,完成优化任务的编译器就叫做及时编译器, just in time compiler
 client 提高编译速度; server 提高编译质量;是为了适应不同的场景;
 对“只执行一次”的代码而言,解释执行其实总是比JIT编译执行要快。
 *输入的代码 -> [ 解释器 解释执行 ] -> 执行结果
 
 *输入的代码 -> [ 编译器 编译 ] -> 编译后的代码 -> [ 执行 ] -> 执行结果
1、只被调用一次,例如类的构造器(class initializer,())
2、没有循环
只有对频繁执行的代码,JIT编译才能保证有正面的收益。

在处理器内核中一般会有多个执行单元,比如算术逻辑单元、位移单元等。
在引入并行指令集之前,CPU在每个时钟周期内只能执行单条指令,也就是说只有一个执行单元在工作,其他执行单元处于空闲状态;
在引入并行指令集之后,CPU在一个时钟周期内可以同时分配多条指令在不同的执行单元中执行。
这种优化的本质是通过提前执行其他可执行指令来填补CPU的时间空隙
Java编译器、CPU指令重排序都需要保证在单线程环境下的as-if-serial语义是正确的。
3编译器和处理器不会对存在依赖关系的操作进行指令重排序;

指令重排对双重检测机制有可能造成结果不是想要的;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值