编译器对代码的 reorder

原创 2011年01月09日 14:28:00

 

http://www.cs.umd.edu/users/pugh/java/memoryModel/jsr-133-faq.html#reordering

 

What is meant by reordering?

There are a number of cases in which accesses to program variables (object instance fields, class static fields, and array elements) may appear to execute in a different order than was specified by the program. The compiler is free to take liberties with the ordering of instructions in the name of optimization. Processors may execute instructions out of order under certain circumstances. Data may be moved between registers, processor caches, and main memory in different order than specified by the program.

For example, if a thread writes to field a and then to field b, and the value of b does not depend on the value of a, then the compiler is free to reorder these operations, and the cache is free to flush b to main memory before a. There are a number of potential sources of reordering, such as the compiler, the JIT, and the cache.

The compiler, runtime, and hardware are supposed to conspire to create the illusion of as-if-serial semantics, which means that in a single-threaded program, the program should not be able to observe the effects of reorderings. However, reorderings can come into play in incorrectly synchronized multithreaded programs, where one thread is able to observe the effects of other threads, and may be able to detect that variable accesses become visible to other threads in a different order than executed or specified in the program.

Most of the time, one thread doesn't care what the other is doing. But when it does, that's what synchronization is for. 

 

稍稍翻译下:


reordering 意味着什么

 

对 variable(instance field, class field, or component of array,绝不包括method parameter, local variable) 的访问并不按程序指定的顺序进行,而是以其他不同顺序执行,这种情形,在很多情况下都会出现
1、编译器可以以优化的形式自由的 reordering 程序指令。
2、处理器在某些情况下会打乱程序指令顺序来执行(提高执行速度,当然,在保证程序正确前提下)。
3、寄存器、处理器缓存以及内存之间 的数据移动可能也会以和程序所指定的顺序 不同的顺序来执行

 

例如,某个线程写入 field a,然后写入 field b,并且 b 的值不会依赖于 a 的值,此时,
a)、编译器可以自由的 reordering 这些指令,
b)、缓存也可以先于 a 将 b 的值刷新到内存
c)、很多潜在的因素都会影响到 重排序,比如,编译器,JIT以及cache

 

编译器、运行时环境、硬件都被期望来产生 “貌似顺序化操作”的语义(create the illusion of as-if-serial semantics),也就是说,在单线程环境中,程序不应该看到 reordering 所产生的影响。

 

但是,在未能正确同步的多线程程序中,reordering 的影响就凸显出来了,这种情况下

a)、一个线程可以看到另一个线程 reordering 所产生的影响

b)、一个线程可能会发觉 自己对变量的访问对另一个线程可见,但是,这个可见不是以 真正执行的或者程序所指定 的顺序,而是以其他不同的顺序所可见的

 

多数情况下,一个线程并不会关心其他线程在做什么(这里的“做什么”就是指对variable做了何种操作。因为线程间不能进行交互,他们的沟通仅仅在于操作同一个variable)。但是,如果使用了synchronized,此线程就会关心“其他线程对vairable做了什么”

 

看其他资料时产生的疑问

http://www.javaeye.com/topic/260515/

 

同一个线程执行上面的两个操作,操作A:x = 3和操作B:y = 2。根据单线程规则,操作A

happen-before操作B,但是操作A却不一定在时间上先于操作B发生,这是因为编译器的重新排

序等原因,操作B可能在时间上后于操作B发生。这个例子也说明了,分析操作上先后顺序是多

么地不靠谱,它可能完全违反直观感觉。

 

我的理解:

1、如果我认为:“即使在同一个线程中,依然存在compiler调整语句的顺序”

 

2、如果我认为:“调整语句顺序,仅仅是‘在其他线程看来,调整了顺序’(因为其他线程看到

后面的操作有正确值了,前面的操作却还没有,即 后面的操作在main memory中看到了,但是,前面的操作在main memory中却还看不到)”

 

 

结论就是:即使同一个线程中,compiler依然会调整语句顺序。只是,同一个线程中,语句的调整,对单线程 没有任何影响;但是,这个调整产生的影响被其他线程看到了

 

ggplot2画图工作中的代码总结

工作中经常要ggplot各种图形,下面是这几个月用ggplot画图的一些代码,最经常碰到的情况就是各个类别下的频率,在柱状图中每个分类上显示百分比,各个类别对应的字体要倾斜,各个图的颜色什么的,总之一...
  • luoyexuge
  • luoyexuge
  • 2015年10月13日 21:39
  • 1720

函数的功能与坐标轴的理解

函数实现从 x →\rightarrow y 的映射;如果 xx 的取值范围固定,无论是 f(x),g(x),g(12x)f(x),g(x),g(\frac12x),其自变量的取值范围都是固定的;...
  • lanchunhui
  • lanchunhui
  • 2016年08月10日 15:45
  • 399

C编译器剖析_6.1 汇编代码生成_简介

6.1 汇编代码生成简介     历经词法分析、语法分析、语义检查和中间代码生成阶段,我们终于来到了“目标代码生成阶段”,由于UCC编译器的目标代码即为32位x86汇编代码,因此我们就把本章称为“汇...
  • SheIsC
  • SheIsC
  • 2015年04月25日 19:24
  • 1158

解释器与编译器

计算机不能直接认识并执行我们写的语句,它只能认识机器语言(是二进制的形式)。 编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很...
  • hellojoy
  • hellojoy
  • 2015年07月24日 18:39
  • 2037

一个简单的C语言编译器

源代码: // // #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AN...
  • zxxSsdsd
  • zxxSsdsd
  • 2013年08月07日 18:32
  • 4603

浅析代码优化——编译器优化原理

开篇 相信有过编码经验的人都知道,程序的正常运行,只是最基本的要求。更多的,还要考虑程序的性能,运行效率,组织结构,和重用性等等。 今天将简单的讨论一下如何优化程序性能。 要写出高效的程序,可能...
  • John_ToStr
  • John_ToStr
  • 2016年08月25日 14:57
  • 782

编辑器与编译器详解

首先说下概念 编辑器:说白了就一个类似于text或者office型的编辑工具,只是这个编辑器是针对代码编辑的。 编译器:将你所编辑的源代码编译成机器所能理解的语言,比如VC++把你的.cpp文件编译成...
  • u014492609
  • u014492609
  • 2015年01月04日 17:01
  • 1959

代码变成可执行程序期间,编译器做了那些事?

代码变成可执行程序期间,编译器做了那些事? 1. 怎么就在编译时确定了 sizeof 的大小了? 2.编译时确定的东西? 3.运行时确定的东西?      ...
  • u014774781
  • u014774781
  • 2015年09月20日 11:10
  • 1068

FreeRTOS 第二课:启动文件分析

freertos的启动分析、stm32f103固件库的启动分析
  • qqliyunpeng
  • qqliyunpeng
  • 2016年12月13日 22:23
  • 1736

编辑器、编译器和链接器的概念和区别

1.集成开发环境: “集成”二字就是字面意思,集成开发环境整合了编辑器、编译器、链接器,调试,部署,乃至代码版本管理等功能于一体,为了方便程序员编写,编译,调试程序和部署程序。 以下内容转载于 ...
  • ios_xumin
  • ios_xumin
  • 2017年06月19日 10:16
  • 645
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:编译器对代码的 reorder
举报原因:
原因补充:

(最多只允许输入30个字)