指令重排相关

news2024/9/9 4:10:09

指令流水线所带来的一些问题

  1. 结构冒险

    流水线中出现硬件资源竞争

  2. 数据冒险

    流水线中后面的指令需要等待前面指令完成数据的读写

  3. 控制冒险

    流水线需要个怒前面指令的执行结果来决定下一步去哪儿之行

为了解决指令流水线的数据冒险所带来的停顿、CPU 搞了个乱序执行。

在遇到数据冒险时、指令调度单元从中选择一些没有数据依赖的指令来执行。后面再进行结果回写时、才按原有顺序进行回写。

这就是 CPU 带来的乱序执行。

Java 编译器处于 “优化” 的目的、按照某种规则将指令重新排序(尽管有时候看起来像乱序)

这就是编译器带来的乱序。

因为 CPU 缓存同步顺序带来伪乱序。

在这里插入图片描述

以上即是导致重排序的三种原因。

在这里插入图片描述

我们先来看看 CPU 缓存所带来的一些问题

比如现在两个 CPU 都对变量 i 进行 +1、现在 i 在内存中的值为 0 (非并发 + 1)

那么

  1. CPU1 从内存中将 i 值放入到自己的缓存中
  2. CPU1 对 i 值进行 +1、并将结果写到自己的缓存中
  3. CPU2 中的缓存中已经存在i的值了(可能是上一次读取缓存的)
  4. CPU2 对 i 值进行 +1、并将结果写到自己的缓存中
  5. CPU1和 CPU2 将自己缓存的 i 写回到内存中

此时 i 被加了两次、但是结果只有一次的的值。

缓存一致性协议 MESI

在这里插入图片描述

我们在来看看上面这个流程

  1. CPU1 从内存中将 i 值放入到自己的缓存中、此时该缓存行的状态位 S (CPU2 中也有该缓存、状态为 S)
  2. CPU1 发出失效命令、告知 CPU2 将它的缓存行状态置为I失效。CPU2 将 i 的缓存行状态更新为 I 并且回复 CPU1 ack 消息
  3. CPU1 收到 ack 消息之后将缓存行的状态由 S 变为 E
  4. 然后CPU1 对 i 值进行 +1、并将结果写到自己的缓存中、此时状态变为 M
  5. CPU2 对 i 值进行 +1 前发现 i 的缓存行位 I、发起读取、CPU1 收到请求、先将 i 刷回到 内存、状态变为 E 然后再发 i 的值给 CPU2 然后状态变为 S。然后 CPU2 再发起失效命令
  6. CPU2 对 i 值进行 +1、并将结果写到自己的缓存中
  7. CPU2 将自己缓存的 i 写回到内存中

(事实上获取i和失效命令会同时发出、invalidate read)

那么最终 i 会被正确的+1

上面这里并非是一个并发+1的场景、也可以是一个串行的场景、只不过第一次和第二次的+1分配到不同的 cpu 上。

通过 MESI 协议、貌似解决了缓存一致性的问题。

但是我们每次都需要等待到其他 CPU 的 ack 才能去执行指令、这样子太慢了、并且其他 CPU 也可能并不是马上会去执行失效请求的、因为可能它可能正在执行其他高优先级的指令。

所以又引入了另一个组件、store buffer

在这里插入图片描述

它的作用很简单

  1. CPU1 发起失效请求之后、CPU1 不会等其他 CPU 的 ack、而是马上执行指令、然后将执行的结果存放在 store buffer。由 store buffer 等待其他 CPU 回复 ack 、然后才将执行结果刷回到 CPU 的

但是这样子也会带来问题、比如我们下面的这段代码(ARM 架构上)

    int x = 0;
    int y = 0;

    private void write(){
   
        x = 1;
        y = 1;
    }
    
    private void read(){
   
        System.out.println(y);
        System.out.println(x);
    }

假设 x 的值已经被更新在 store buffer 了、这个时候 cpu 缓存里面 x 的值还是 0

这个时候 cpu 就会继续执行 y=1 假如这个时候 y

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/841117.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于Godot游戏引擎制作流水灯

先上核心代码 游戏节点 流水灯的通途可以是 1. 装饰 2. 音乐类多媒体程序(如FL中TB-303的步进灯) FL Studio Transistor Bass

TypeScript 中【class类】与 【 接口 Interfaces】的联合搭配使用解读

导读: 前面章节,我们讲到过 接口(Interface)可以用于对「对象的形状(Shape)」进行描述。 本章节主要介绍接口的另一个用途,对类的一部分行为进行抽象。 类配合实现接口 实现(impleme…

8.7工作总结

一、我们想自定义一个titileBar出现如下这种情况,发现他原来的titileBar还未隐藏。 后来我尝试修改主题使得他没有主题noActionBar发现也不行,后来我参考原先我看过的项目使用了如下代码 this.getActionBar().hide();发现会报这个错误java.lang.NullPoi…

30.基于XML的声明式事务

基于XML的声明式事务 主要是使用XML去代替注解&#xff0c;来实现起到代替注解的作用&#xff0c;实际使用频率很低 将BookServiceImpl.java中的Transactional注解删除&#xff0c;确保用户余额充足 spring-tx-xml.xml <?xml version"1.0" encoding"UTF-8…

Android AccessibilityService研究

AccessibilityService流程分析 AccessibilityService开启方式AccessibilityService 开启原理 AccessibilityService开启方式 . 在Framework里直接添加对应用app 服务component。 loadSetting(stmt, Settings.Secure.ACCESSIBILITY_ENABLED,1); loadSetting(stmt, Settings.Se…

mybatis-plus的update方法,到底会不会更新null值?看这一篇就够了

普通的设置值。需要传入一个Wrapper对象 默认情况下是不会更新null值的&#xff0c;也就是只更新设置值的字段 LambdaUpdateWrapper<OrderChildRoom> orderChildRoomUpdateWrapper new LambdaUpdateWrapper<>();orderChildRoomUpdateWrapper.set(OrderChildRoo…

【PDF密码】PDF文件不能打印,为什么?

正常的PDF文件是可以打印的&#xff0c;如果PDF文件打开之后发现文件不能打印&#xff0c;我们需要先查看一下自己的打印机是否能够正常运行&#xff0c;如果打印机是正常的&#xff0c;我们再查看一下&#xff0c;文件中的打印功能按钮是否是灰色的状态。 如果PDF中的大多数功…

面试热题(滑动窗口最大值)

给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 输入&#xff1a;nums [1,3,-1,-3,5,3,6,7], k 3 输出&#xff1a;[3,3,5,…

SpringCloud实用篇1——eureka注册中心 Ribbon负载均衡原理 nacos注册中心

目录 1 微服务1.1 微服务的演变1.2 微服务1.3 SpringCloud1.4 小结 2 服务拆分及远程调用2.1 服务拆分2.2 服务拆分案例2.3 实现远程调用2.4 提供者与消费者 3 Eureka注册中心3.1 Eureka的结构和作用3.2 搭建eureka-server3.3 服务注册3.4 服务发现 4 Ribbon负载均衡4.1 负载均…

ubuntu18.04安装docker及docker基本命令的使用

官网安装步骤&#xff1a;https://docs.docker.com/desktop/install/ubuntu/ docker快速入门教程 Ubuntu-Docker安装和使用 docker官网 docker-hub仓库 1、常用指令 &#xff08;1&#xff09;镜像操作 # ############################# 以nginx为例 docker images docker p…

爬虫010_列表高级_添加_append_extend_修改_查询_in_not int_删除_del_pop_remove---python工作笔记029

然后再来看列表操作 首先添加append方法 然后插入,坐标是要插入的下标,右边是插入的内容 看结果 1,2,3,4,5,6 然后这个extend,是逐个插入,放到后边 然后是修改,直接对下标赋值 看结果</

宝塔面板点击SSL闪退打不开怎么解决?

宝塔Linux面板点击SSL证书闪退如何解决&#xff1f;旧版本的宝塔Linux面板确实存在这种情况&#xff0c;如何解决&#xff1f;升级你的宝塔Linux面板即可。新手站长分享宝塔面板SSL闪退的解决方法&#xff1a; 宝塔面板点击SSL证书闪退解决方法 问题&#xff1a;宝塔Linux面板…

创建独立 Python 环境的工具venv

venv 是一种用于创建独立 Python 环境的工具。这些隔离环境可以具有单独的 Python 软件包版本&#xff0c;以便将一个项目的依赖项与其他项目的依赖项隔离开来。我们建议您在使用 Python 进行本地开发时始终使用每个项目的虚拟环境。 1.使用 venv 命令创建整个 Python 安装的虚…

Vue系列第七篇:Element UI之el-main,el-table,el-dialog,el-pagination,el-breadcrumb等控件使用

本篇实现主页面功能&#xff0c;包括主页面排版布局&#xff0c;学生管理模块实现&#xff0c;后台接口实现等功能。 目录 1.运行效果 1.1登录页面 1.2主页面 1.3学生管理 - 信息列表 1.4学生管理 - 信息管理 1.5学生管理 - 作业列表 1.6学生管理 - 作业管理 2.前端代码…

Spring MVC简介与概述

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

设计模式之六:命令模式(封装调用)

命令模式可以将请求的对象和执行请求的对象解耦&#xff08;实际上是通过命令对象进行沟通&#xff0c;即解耦&#xff09;。&#xff08;个人感觉&#xff0c;这章讲的很一般&#xff09; 按个人理解来讲&#xff1a; 假如需要一个遥控器&#xff0c;遥控器有一个插口可以插上…

Python以及Pycharm保姆级的下载安装教程,看完就懂

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Python的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Python的安装 1.下载地址 2.下载步骤…

UITabBarController上边的线,iOS15

新建的UITabBarController是下面这个样子的。 但是想要的是如下的形式&#xff1a; 查了一下这个要通过 tab.scrollEdgeAppearance 来修改。 具体修改方式如下&#xff1a; let appearance self.tabBar.standardAppearance.copy() appearance.backgroundColor .white appear…

如何通过 WordPress 数据库启用插件?【进不去后台可用】

如果您无法访问 WordPress 后台并需要激活插件以恢复访问权限&#xff0c;则可以通过 WordPress 数据库来实现。本文将向您展示如何使用数据库轻松激活 WordPress 插件。 何时使用数据库激活 WordPress 插件&#xff1f; 许多常见的 WordPress 错误会阻止网站所有者访问 WordP…