Java并发编程-57什么是指令重排序?为什么要重排序?

57 什么是指令重排序?为什么要重排序?

本课时我们主要介绍什么是重排序?为什么要重排序? 什么是重排序

假设我们写了一个 Java 程序,包含一系列的语句,我们会默认期望这些语句的实际运行顺序和写的代码顺序一致。但实际上,编译器、JVM 或者 CPU 都有可能出于优化等目的,对于实际指令执行的顺序进行调整,这就是重排序。 重排序的好处:提高处理速度

你可能感到很困惑,为什么要重排序?这样做有什么好处呢?

我们来举一个具体的例子。

img

图中左侧是 3 行 Java 代码,右侧是这 3 行代码可能被转化成的指令。可以看出 a = 100 对应的是 Load a、Set to 100、Store a,意味着从主存中读取 a 的值,然后把值设置为 100,并存储回去,同理, b = 5 对应的是下面三行 Load b、Set to 5、Store b,最后的 a = a + 10,对应的是 Load a、Set to 110、Store a。如果你仔细观察,会发现这里有两次"Load a"和两次"Store a”,说明存在一定的重排序的优化空间。

经过重排序之后,情况如下图所示:

img

重排序后, a 的两次操作被放到一起,指令执行情况变为 Load a、Set to 100、Set to 110、 Store a。下面和 b 相关的指令不变,仍对应 Load b、 Set to 5、Store b。

可以看出,重排序后 a 的相关指令发生了变化,节省了一次 Load a 和一次 Store a。重排序通过减少执行指令,从而提高整体的运行速度,这就是重排序带来的优化和好处。 重排序的 3 种情况

下面我们来看一下重排序的 3 种情况。

(1)编译器优化

编译器(包括 JVM、JIT 编译器等)出于优化的目的,例如当前有了数据 a,把对 a 的操作放到一起效率会更高,避免读取 b 后又返回来重新读取 a 的时间开销,此时在编译的过程中会进行一定程度的重排。不过重排序并不意味着可以任意排序,它需要需要保证重排序后,不改变单线程内的语义,否则如果能任意排序的话,程序早就逻辑混乱了。

(2)CPU 重排序 CPU 同样会有优化行为,这里的优化和编译器优化类似,都是通过乱序执行的技术来提高整体的执行效率。所以即使之前编译器不发生重排,CPU 也可能进行重排,我们在开发中,一定要考虑到重排序带来的后果。

(3) 内存的"重排序”

内存系统内不存在真正的重排序,但是内存会带来看上去和重排序一样的效果,所以这里的"重排序"打了双引号。由于内存有缓存的存在,在 JMM 里表现为主存和本地内存,而主存和本地内存的内容可能不一致,所以这也会导致程序表现出乱序的行为。

举个例子,线程 1 修改了 a 的值,但是修改后没有来得及把新结果写回主存或者线程 2 没来得及读到最新的值,所以线程 2 看不到刚才线程 1 对 a 的修改,此时线程 2 看到的 a 还是等于初始值。但是线程 2 却可能看到线程 1 修改 a 之后的代码执行效果,表面上看起来像是发生了重顺序。 总结

以上就是本课时的内容。本课时我们首先用一个例子介绍了什么是重排序,然后分析了重排序所能带来的好处,并介绍了可能发生重排序的 3 种情况

文章列表

更多推荐

更多
  • Linux基础知识-五、更高级的命令行和概念 基本网络概念,安装新软件和更新系统,服务介绍,基本系统故障排除和防火墙,引入 ACLs,setuid、setgid 和粘性位,设置用户标识符,塞吉德,粘性比特,摘要, 在本章中,我们将了解以下内容:基本网络概念安装新
  • Linux基础知识-三、Linux 文件系统 理解文件系统,使用文件链接,搜索文件,与用户和组一起工作,使用文件权限,使用文本文件,使用 VIM 文本编辑器,摘要, 在前一章中,我们通过导航文件系统向您介绍了 Linux 文件和文件夹。在本章中,我们将学习如何使用、查找和更改读取和
  • Linux基础知识-四、使用命令行 基本的 Linux 命令,附加程序,网络工具,Nmap(消歧义),链接,iotop,iftop,快上来,lsof,理解过程,克隆,信号,杀,障碍,使用 Bash Shell 变量,Bash shell 脚本介绍,实现 Bash Shel
  • Linux基础知识-二、Linux 命令行 介绍命令行,文件环球化,引用命令,寻求帮助,使用 Linux Shell,理解标准流,理解正则表达式,与 sed 合作,使用 awk,浏览 Linux 文件系统,摘要, 在本章中,我们将向您介绍开始使用 Linux 命令行时最基本的概念
  • Linux基础知识-一、Linux 简介 Linux 系统概述,虚拟化,安装 VirtualBox 和 CentOS,使用 VirtualBox,通过 SSH 连接虚拟机,摘要, 一个操作系统 ( 操作系统)是一个运行在你的电脑上的特殊软件,它使得启动和运行微软
  • Linux基础知识-零、前言 这本书是给谁的,这本书涵盖了什么,充分利用这本书,下载彩色图像,使用的约定,取得联系,复习, 在这本书里,目标是建立一个坚实的基础,学习 Linux 命令行的所有要点,让你开始。它被设计成非常专注于只学习实用的核心技能和基本的 Linu
  • Git秘籍-十二、使用 Github 在这一章中,我将讨论使用 Github 来托管存储库。目前这是一个流行的开源项目托管平台。我们首先创建一个 Github 帐户并配置 SSH 密钥。完成后,您将学会如何:从公共 Github 库克隆克隆并推送至
    Apache CN

  • Git秘籍-十三、更多秘籍 在这最后一章,我将讨论一些尚未涉及的细节,这些细节迟早会成为你不可或缺的。您将了解到:如何使用命令`$ git diff`比较不同版本的文件?如何克服关于行尾的问题?配置忽略文件的三种不同方法使
    Apache CN

  • Git秘籍-十一、托管 Git 存储库 一旦你和你的同事们学会了如何提交、使用分支和远程操作,你就会想把 git 作为一个团队来使用。在这一章中,我将展示如何建立一个虚拟主机来与他人共享 git 库。 Git 可以使用 ssh、http、https 和 git 网络协议。要
    Apache CN

  • Git秘籍-十、远程存储库和同步 所有 VCS 系统背后的内在原因是使一组开发人员之间的协作尽可能无缝。最后,我们已经到了可以讨论如何使用 git 进行小组工作的时候了。我们将从最简单的设置开始,所有的存储库都可以通过本地存储获得。首先你必须学会如何使用遥控器。我
    Apache CN

  • 近期文章

    更多
    文章目录

      推荐作者

      更多