流水线中的大冒险

简介:

上一节说到,流水线中的分支预测本身是为了提高整条流水线的并行度,为此,CPU做了很多努力,例如乱序执行,甚至于流水线本身也是为了这个目的而诞生的。

和我们编写一般程序一样,顺序执行总是最简单、最安全的,指令被一条接着一条地顺序执行,没有人会思考任何有关并发的隐患。但是一旦踏入并发编程的范畴,似乎就开始变得一团糟,你需要考虑数据竞争、锁、内存等等一系列问题。和分支预测一样,有时候你会采用一些试探性的方法去处理并发中产生的问题,例如经典的CAS(Compare And Swap)算法,可能成功可能失败,喜忧参半。

在流水线中也存在着类似的大冒险,典型的有三种:

数据冒险

结构冒险

控制冒险

对应的,也有一些方法去辅助CPU在这些冒险的过程中,尽可能地达到我们期望的结果。

一、数据冒险

数据冒险源于在流水线的乱序执行中,读写之间产生的数据依赖,例如写后读,如果在一条指令的读之前,刚好有另一条指令完成了对相同位置的写,那么按常理来说,读的指令读到的数据必须是刚被写入的那个值。

看起来是不是很眼熟?是的,这跟Java中的Happens-Before法则是一致的,扩展开的话,数据库中的一致性以及Java中的volatile,本质上都是在确保同样的效果。

我们知道经典的CPU是通过ALU进行计算的,而数据的输入则在通用寄存器中,事实上为了支持流水线,在ALU和通用寄存器之间,还有一些额外的寄存器,这些寄存器对程序员不可见,被称作流水线寄存器,它们的作用也很简单,保存在流水线的执行过程中,各个时钟周期的结果暂存。

对于经典的五级流水线来说,一条指令的执行周期要经过以下过程:

IF: Instruction Fetch – 取址

ID: Instruction Decode and register fetch – 译码

EX: Execution and effective address calculation – 执行

MEM:  Memory access – 内存访问

WB:  Write Back – 写回通用寄存器

那么试想一下,假设现在有两条指令的执行路径如下:

I1: IF – ID – EX – MEM – WB

I2:       IF – ID –   EX   – MEM – WB

I1的结果在EX之后被写入流水线寄存器暂存,此时还没写入内存,也没写入通用寄存器。

这个时候I2在EX阶段要取I1的结果,按道理是拿不到的。

最简单的,I2等待2个时钟周期,等I1把结果写入通用寄存器后,再去读取。这是一种解决方式。

CPU还可能会采用被称作Register Forwarding的机制获取数据,简单来说就是I1的流水线寄存器中的数据直接转发作为I2的EX的输入,此时I2的EX就不会受到影响,并且避免了等待造成的浪费。

二、结构冒险

结构冒险是当CPU同时有多条指令要访问同一个硬件资源时造成的冲突。例如同时对内存的访问,但同时只能提供一条指令的访问。

结构冒险在早期的冯·诺依曼架构中是个问题,因为数据和指令是存在一起的,IF和MEM就会发生冲突。而现代处理器在L1 Cache层将指令和数据分开,分为L1 Cache(I)和L1 Cache(D),避免了这个竞态问题。

三、控制冒险

控制冒险和上一节说到的分支预测关系密切。

首先想象一下如果没有分支预测,那么当流水线遇到跳转语句时,它会认为跳转这个时间点开始进入新的起点,所有事先被执行的指令都不对。这时CPU需要插入若干个停顿周期,直到一切恢复原点。

某些处理器会通过插入NOP指令的方式来停顿若干个时钟周期,而某些处理器干脆排空所有的当前指令(被称作流水线冲刷(Pipeline Flush)。

除了分支预测,另一种优化方式是将插入的等待NOP指令改为不相关的乱序执行的有效指令,利用等待时间的开销。

目录
相关文章
|
6月前
|
人工智能 JavaScript 架构师
流水线运行出错排查难?AI 来帮你
目前云效流水线 Flow 内 Java 构建、Node.js 构建、Java 单元测试、Node.js 单元测试这 4 个步骤均接入了智能排查的能力。
42327 4
|
6月前
|
并行计算 数据挖掘 数据处理
【软件设计师备考 专题 】CISC RISC,流水线操作,多处理机,并行处理
【软件设计师备考 专题 】CISC RISC,流水线操作,多处理机,并行处理
132 0
|
监控 数据可视化 中间件
平台化三部曲之三流程编排 - 平台化是舞台,流程编排就是导演一场戏
在上两篇ATA中,第一篇讨论了平台的扩展性(《从Eclipse平台看交易平台化》),强调微内核和扩展机制实现,第二篇讨论平台的模块化开发(《Google Guice平台模块化开发的果汁》),强调业务隔离,松耦合。这这第三篇ATA中,想分享下平台化中另一个重要方面,平台的服务流程编排 (*备注:本文.
17964 0
|
3月前
|
敏捷开发 安全 测试技术
阿里云云效产品使用合集之工作负荷指的是什么意思
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
5月前
|
数据采集 安全 网络安全
阿里云云效产品使用问题之流水线的环境可以在什么地方进行配置
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
4月前
|
敏捷开发 缓存 JavaScript
阿里云云效产品使用合集之流水线运行慢该如何优化
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
5月前
|
缓存 运维 Kubernetes
阿里云云效操作报错合集之有几个老项目流水线,部署过程一直是部署中不结束,该怎么办
本合集将整理呈现用户在使用过程中遇到的报错及其对应的解决办法,包括但不限于账户权限设置错误、项目配置不正确、代码提交冲突、构建任务执行失败、测试环境异常、需求流转阻塞等问题。阿里云云效是一站式企业级研发协同和DevOps平台,为企业提供从需求规划、开发、测试、发布到运维、运营的全流程端到端服务和工具支撑,致力于提升企业的研发效能和创新能力。
|
5月前
|
达摩院 供应链 调度
【FlowShop流水线作业排班问题【数学规划的应用(含代码)】阿里达摩院MindOpt】
本文探讨了使用阿里巴巴达摩院的MindOpt工具解决FlowShop流水线作业排班的数学规划问题。FlowShop涉及到多台机器、多个工序和多个作业,目标是通过优化排班最小化总生产耗时。MindOpt通过数学规划方法,如线性或混合整数线性规划,将问题建模并转化为代码,利用云建模平台MindOpt Studio和MindOpt APL建模语言进行求解。案例中详细介绍了参数定义、变量解析、约束设置和目标函数,展示了如何通过MindOpt进行建模和求解,以达到最优化的生产调度。此外,文章还提供了代码示例和结果解析,帮助读者理解如何实际应用MindOpt解决这类问题。
|
6月前
|
存储 缓存 Windows
软件体系结构 - 流水线技术
软件体系结构 - 流水线技术
92 0
|
6月前
|
存储 达摩院 调度
「达摩院MindOpt」优化FlowShop流水线作业排班问题
在企业在面临大量多样化的生产任务时,如何合理地安排流水线作业以提高生产效率及确保交货期成为了一个重要的问题。
「达摩院MindOpt」优化FlowShop流水线作业排班问题