前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从源代码到Runtime发生的重排序编译器重排序指令重排序内存系统重排序阻止重排序

从源代码到Runtime发生的重排序编译器重排序指令重排序内存系统重排序阻止重排序

作者头像
用户1174983
发布2018-02-05 15:40:38
1.4K0
发布2018-02-05 15:40:38
举报
文章被收录于专栏:钟绍威的专栏钟绍威的专栏

 源代码和Runtime时执行的代码很可能不一样,这是因为编译器、处理器常常会为了追求性能对改变执行顺序。然而改变顺序执行很危险,很有可能使得运行结果和预想的不一样,特别是当重排序共享变量时。

 从源代码到Runtime需要经过三步的重排序:

重排序过程
重排序过程

编译器重排序

 为了提高性能,在不改变单线程的执行结果下,可以改变语句执行顺序。

 比如尽可能的减少寄存器的读写次数,充分利用局部性。像下面这段代码这样,交替的读x、y,会导致寄存器频繁的交替存储x和y,最糟的情况下寄存器要存储3次x和3次y。如果能让x的一系列操作一块做完,y的一块做完,理想情况下寄存器只需要存储1次x和1次y。

代码语言:javascript
复制
//优化前
int x = 1;
int y = 2;
int a1 = x * 1;
int b1 = y * 1;
int a2 = x * 2;
int b2 = y * 2;
int a3 = x * 3;
int b3 = y * 3;

//优化后
int x = 1;
int y = 2;
int a1 = x * 1;
int a2 = x * 2;
int a3 = x * 3;
int b1 = y * 1;
int b2 = y * 2;
int b3 = y * 3;

指令重排序

 指令重排序是处理器层面做的优化。处理器在执行时往往会因为一些限制而等待,如访存的地址不在cache中发生miss,这时就需要到内存甚至外存去取,然而内存和外区的读取速度比CPU执行速度慢得多。

 早期处理器是顺序执行(in-order execution)的,在内存、外存读取数据这段时间,处理器就一直处于等待状态。现在处理器一般都是乱序执行(out-of-order execution),处理器会在等待数据的时候去执行其他已准备好的操作,不会让处理器一直等待。

 满足乱序执行的条件:

  1. 该缓存的操作数缓存好
  2. 有空闲的执行单元

 对于下面这段汇编代码,操作1如果发生cache miss,则需要等待读取内存外存。看看有没有能优先执行的指令,操作2依赖于操作1,不能被优先执行,操作3不依赖1和2,所以能优先执行操作3。 所以实际执行顺序是3>1>2

代码语言:javascript
复制
LDR R1, [R0];//操作1
ADD R2, R1, R1;//操作2
ADD R3, R4, R4;//操作3

内存系统重排序

 由于处理器有读、写缓存区,写缓存区没有及时刷新到内存,造成其他处理器读到的值不是最新的,使得处理器执行的读写操作与内存上反应出的顺序不一致

 如下面这个例子,可能造成处理器A读到的b=0,处理器B读到的a=0。A1写a=1先写到处理器A的写缓存区中,此时内存中a=0。如果这时处理器B从内存中读a,读到的将是0。

 以处理器A来说,处理器A执行的顺序是A1>A2>A3,但是由于写缓存区没有及时刷新到内存,所以实际顺序为A2>A1>A3。

代码语言:javascript
复制
初始化:
a = 0;
b = 0;

处理器A执行
a = 1; //A1
read(b); //A2

处理器B执行
b = 2; //B1
read(a); //B2
处理器和内存的交互
处理器和内存的交互

阻止重排序

 不论哪种重排序都可能造成共享变量中线程间不可见,这会改变程序运行结果。所以需要禁止对那些要求可见的共享变量重排序。

  • 阻止编译重排序:禁止编译器在某些时候重排序。
  • 阻止指令重排序和内存系统重排序:使用内存屏障或Lock前缀指令
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-12-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 编译器重排序
  • 指令重排序
  • 内存系统重排序
  • 阻止重排序
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档