(说明:本文 不是博主原创文章,原文链接:https://aijishu.com/a/1060000000216149)

现在的处理器执行方式分为两种,顺序执行和乱序执行。根据不同的产品定位,不同的应用场景,所使用的微架构也是不相同的。

1、顺序执行解析

顺序执行的处理器一般用于低功耗类型的处理器,比如ARM公司的cortex-M系列都是顺序执行的,如果要稍微性能和功耗兼顾的产品,也是使用的顺序执行的方式。

何为顺序执行,顾名思义,亦就是按照PC的取指顺序,一条一条的执行。遇到数据相关性就停下等待,当然,可以进行 数据旁路的就进行数据旁路加快一下效率。

相比较之下,顺序执行所需要的硬件开销是比较小的。这是因为顺序执行不需要考虑WAW冲突和WAR冲突。即寄存器重命名部件可考虑不使用,仅仅只需要考虑RAW冲突,而RAW冲突是无可避免的,只能通过数据旁路去优化,减少冲突所带来的气泡。

因为相关性的问题,顺序执行一般最多使用双发射结构,再多就浪费了,硬件开销所收获的性能就不成正比。同时,顺序执行不需要额外的监管部件,大家都排好队去执行的,最后按照顺序提交即可。

在此解析一下cortex A53的流水线。ARM公司的cortex A53个人感觉是顺序流水线的巅峰之作了。

Cortex A53是一个顺序双发射8级流水处理器。上图看到最多是十级,那是因为支持NEON浮点运算单元,浮点运算单元时间会比较久。严格在算处理器流水线时,以标量运算为基准。A53在取指时花费三个时钟周期,因为在这一阶段,要做的事情还是比较多的,需要进行分支预测,而且由于是双发的结构,为了提高效率,每次取回一个package的指令是4条,所以取完指令后,会将指令存入 Instruction Queue(指令队列)中,避免后面执行指令没那么快,导致指令丢失。

指令译码会有两个译码单元同时进行译码,提高译码效率。译码完成后送入发射队列中,在发射队列里,会判断指令功能,将指令分发到不同的执行单元中。例如,此时准备好的是一条浮点指令,便将浮点指令送入F0模块中进行运算。是一条标量指令,则把该指令送入ALU运算单元中进行运算。

Cortex A53的coremark性能测试跑分大概在3.1分左右,不算高,但是它将性能和面积之间平衡做得是非常好的。在RISC-V指令集阵营中,不少公司都有产品对标A53处理器,性能是能达到,但是面积或多或少都会比之差一点。当然,ARM公司经过这么多年的经营,其生态是目前的RISC-V无法媲美的,RISC-V在嵌入式领域与ARM竞争目前是不占优势的。

2、乱序执行解析

前文有说过,顺序执行会受到RAW冲突,会造成一定的资源浪费,白白等待很长的时间。为了避免等待,那没有数据相关性的指令是否就能提前去执行呢?那肯定是可以的,所以这就叫乱序执行了。乱序执行的处理器,只是在执行阶段是乱的,在执行阶段以前都是顺序的,按顺序去取指令,按顺序去译码。到了分发段,准备好的指令,没有相关性的指令就可以先行发射,去执行。但是要注意的是,乱序只是执行的时候是乱序,但是在最后提交指令的时候还是按照顺序去提交。

就比如一个公司,有很多订单,一个员工需要上一个员工的给他交接任务才能做,那么在等待的时候,这个员工先做其他的任务,等上一个员工的任务交接给他,他又继续做该任务。最后公司提交这些订单是按照时间顺序提交给客户的,毕竟先来后到。

因此,乱序执行需要一个监管部件,我们称之为 ROB(Re-order Buffer),重排序缓存。

所有的指令都会存在这个单元中,进行备份,并且相应的状态也一并保存。当指令执行完成时,ROB中该指令的状态会被更新,就会将该指令去提交,并移出ROB中。可以把ROB模块理解为一个FIFO,指令在分发段会按照顺序把指令送入保留站,以及ROB模块中,最后会根据指针去进行提交,后面的指令哪怕是执行完成,可以提交了,但是还未到它位置,就不会去提交它。

乱序所需要的硬件开销不止增加ROB模块一个而已,因为乱序执行打破了原有的规则,所以接踵而来的是会有WAW冲突和WAR冲突,这两类冲突需要额外花费相应的硬件去解决掉。比如解决掉WAR冲突就需要使用寄存器重命名的方式去解决。寄存器重命名操作的本质是扩大可用寄存器,在上一篇文章有讲,指令集定义的寄存器组是固定个数的,大家都会去使用,那么将这些寄存器的数量扩大后,可用的寄存器就多了。

比如在一个公司里,大家都需要把资料给到一位老总或者从这位老总手里拿资料,这位老总现在被一帮美女员工所占用,导致其他长得丑的员工没机会去给资料或者拿资料。当然,老板爱美女,更爱江山,为了提高效率,早日开上宝马,就请了一位秘书,说大家把资料给他也行,后面秘书把资料再转交给老板就行。

以上是寄存器重命名操作的举例。读后写(WAR)冲突,情况就是前一条指令需要读一个寄存器,后面一条指令需要对该寄存器写数据进去。如果后一条指令先执行完成,把数据写到该寄存器了,那么前一条指令就极有可能读到一个错误的数据。那先将后一条指令写到另外一个寄存器,也就是上述说的招的秘书,等指令都执行完,再找机会把该寄存器的数据写回到目标寄存器中。

而写后写(WAW)冲突有很多解决办法。前一条指令会对某一个寄存器写数据,后一条指令也是对该寄存器写操作,那么最新的数据就是后一条指令所写的数据,前一条指令的数据我们也就不怎么关心了。所以直接限制前一条指令不写该寄存器了,直接把数据丢掉,让后一条指令写入。但是这样的操作只适用于两条连续的指令,若中间存在RAW冲突,就不太适用了。所以使用寄存器重命名的方式也可以解决此类冲突。

既然使用乱序执行方式了,那么处理器的执行效率也就提上来了,若此时运算单元跟不上,造成结构冲突,那就是一件很丢脸的事情。所以乱序执行的硬件开销更多的都来源于此。浮点运算单元、ALU、访存单元都有多个。并且发射通道也有很多,例如中科院刚刚发布的香山处理器,就是一个6发射的乱序处理器。伯克利大学RISC-V开源处理器Boom最大支持5发射。

3、总结

顺序执行方式和乱序执行方式所应用的场景不同,所使用的架构也会不同。对于嵌入式应用产品(手机除外),一般使用顺序执行的架构即可满足。若面向于一些需要高性能的场景,如手机、电脑、服务器等,一般会采用乱序执行。但是手机这类产品不会单纯的用乱序执行的大核,一般会大小核一起用,即乱序和顺序的处理器都会使用。

顺序执行方式的优势在于硬件开销小,功耗比较低,用于做控制,完成一些简单运算绰绰有余。乱序执行方式的优势在于运算快,对于跑稍微大一点的操作系统或者稍微大一点的运算优势更大一点。在产品上这两者之间如何结合,就需要经验丰富的架构师和产品经理去衡量了。

[architecture]-处理器的顺序和乱序执行相关推荐

  1. Enterprise Architecture 13 将顺序图自动转化为协作图

    我的是试用版的,在试用时会提示你选择一个版本 在这几个版本中,就拿转换功能来说,除了桌面版,其他的都有转换功能,如图最右侧(这个是专业版,下面的功能越来越多吧): 找到这个工具后,就好办了. 选择待转 ...

  2. java多线程编程_《java多线程编程实战指南》读书笔记 -- 基本概念

    展开 并发:多个线程操作相同资源,保证线程安全,合理使用资源 高并发:服务能同时处理多个请求,提高程序性能 测试上下文切换工具 Lmbench3 测量上下文切换时长 vmstat 测量上下文切换次数 ...

  3. 超标量处理器设计 姚永斌 第9章 指令执行 摘录

    9.1 概述 执行阶段负责指令的执行,在流水线的之前阶段做了那么多的事情,就是为了将指令送到这个阶段进行执行.在执行阶段,接受指令的源操作数,对其进行规定的操作,例如加减法.访问存储器.判断条件等,然 ...

  4. 【Linux 内核 内存管理】优化内存屏障 ④ ( 处理器内存屏障 | 八种处理器内存屏障 | 通用内存屏障 | 写内存屏障 | 读内存屏障 | 数据依赖屏障 | 强制性内存屏障 |SMP内存屏障 )

    文章目录 一.处理器内存屏障 二.Linux 内核处理器内存屏障 一.处理器内存屏障 " 处理器内存屏障 " 针对 " CPU " 之间的内存访问乱序 和 CP ...

  5. 【Linux 内核 内存管理】优化内存屏障 ② ( 内存屏障 | 编译器屏障 | 处理器内存屏障 | 内存映射 I/O 写屏障 )

    文章目录 一.内存屏障 二.编译器屏障 三.处理器内存屏障 一.内存屏障 内存屏障 , 又称为 " 屏障指令 " , 用于保证 " 编译器 " 或 " ...

  6. Intel 64/x86_64/x86/IA-32处理器串行化指令(1) - 概述

    Serializing Instructions 注:串行化指令的概念非常容易理解,但是要用好(在哪里用,何时用)则需要深厚的处理器架构和流水线乱序执行的功底.好在大部分应用程序不会用到这类指令. I ...

  7. Pentium 4处理器架构/微架构/流水线 (4) - NetBurst框图

    Intel NetBurst Microarchitecture Overview 与前几代处理器一样,Pentium 4的微架构包括3个主要部分: 有序发射前端 乱序超标量执行核 有序退役单元 流水 ...

  8. X86汇编语言从实模式到保护模式09:32位x86处理器编程架构

    目录 1. IA-32架构的基本执行环境 1.1 寄存器的扩展 1.1.1 通用寄存器的扩展 1.1.2 IP寄存器的扩展 1.1.3 FLAGS寄存器的扩展 1.1.4 段寄存器的扩展 1.2 32 ...

  9. 处理器架构——多发射处理器技术

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 多发射处理器总结 数据冒险 动态调度-Tomasulo算法 GPU与CPU的多发射技术对比(待考究) 多发射处理器总结 无论 ...

最新文章

  1. Vs.net2008 下 Ajaxpro 使用
  2. python方法测试_python 测试常用小方法
  3. 论信息部门与业务部门的关系
  4. vue的 v-for 循环中图片加载路径问题
  5. 深入理解浏览器原理和架构|硬核
  6. react子组件向父组件传递数据实例
  7. mysql虚拟列表_「前端进阶」高性能渲染十万条数据(虚拟列表)
  8. oracle创建一个学生,oracle 创建学生选课视图
  9. AjaxControlToolkit工具控件之Accordion错误解决方法
  10. C++ 运算符重载的原理
  11. oracle rman在线备份,Oracle的RMAN备份与恢复脚本
  12. opencv3错误集锦(四)——Rect函数参数引发的异常中断
  13. python去除图片背景_Python 图片去除背景
  14. ElasticSearch7.3.0 集群搭建及配置安全认证
  15. PHP实现jsapi微信支付
  16. IT行业十大热门职位
  17. sapi/cgi/php-cgi,sapi/cgi/php-cgi
  18. Floating-Point overflow and underflow
  19. python 行情数据_python爬取期权行情数据
  20. python中columns是什么意思_Python Pandas DataFrame.columns用法及代码示例

热门文章

  1. matlab中句点,matlab入门学习(一)
  2. 14种冷热源及空调系统特点介绍
  3. apache2.4.6支不支持jsp_Spring Boot中文参考指南(2.1.6)50、Kotlin 支持
  4. matlab模拟gpd,如何用ARMA模型预测中国GDP
  5. Python编程语言学习:for循环实现对多个不同的DataFrame数据执行相同操作(可用于对分开的测试集、训练集实现执行相同逻辑任务)
  6. Python之pandas:pandas中缺失值与空值处理的简介及常用函数(drop()、dropna()、isna()、isnull()、fillna())函数详解之详细攻略
  7. Keras之DNN:利用DNN【Input(8)→(12+8)(relu)→O(sigmoid)】模型实现预测新数据(利用糖尿病数据集的八个特征进行二分类预测
  8. Algorithm:C++语言实现之图论算法相关(图搜索广度优先BFS、深度优先DFS,最短路径SPF、带负权的最短路径Bellman-ford、拓扑排序)
  9. ML之HierarchicalClustering:自定义HierarchicalClustering层次聚类算法
  10. 源码:我的关于NLP的博客(持续更新中...)