具有指令流水线结构的cpu_cpu流水线技术

具有指令流水线结构的cpu_cpu流水线技术为什么小小一个CPU,有那么多周期(Cycle)?程序的性能,是由三个因素相乘来衡量的,“指令数×CPI×时钟周期”。和周期相关的只有一个时钟周期,即CPU主频的倒数。一个CPU的时钟周期可以认为是可以完成一条最简单的计算机指令的时间。那为何构造CPU时,有那么多周期?单指令周期处理器一条CPU指令的执行,由FDE三步组成。这个执行过程,至少需花费一个时钟周期。因为在取指令的时候,我们需要通过时钟周期的信号,来决定计数器的自增。很自然,我们希望能确保让这样一整条指令的执行,在一个时钟周期内完成

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

为什么小小一个CPU,有那么多周期(Cycle)?

程序的性能=指令数×CPI×时钟周期,和周期相关的只有一个时钟周期,即CPU主频的倒数。
一个CPU的时钟周期可以认为是可以完成一条最简单的计算机指令的时间。

那为何构造CPU时,有那么多周期?

单指令周期处理器

一条CPU指令的执行,由FDE三步组成。这个执行过程,至少需花费一个时钟周期。因为在取指令的时候,我们需要通过时钟周期的信号,来决定计数器的自增。

很自然,我们希望能确保让这样一整条指令的执行,在一个时钟周期内完成。
这样,一个时钟周期可执行一条指令,CPI=1,看着就比执行一条指令要多个时钟周期性能好。
这就是单指令周期处理器(Single Cycle Processor):一个时钟周期内,处理器正好能处理一条指令。

但时钟周期固定,指令的电路复杂程度不同,所以实际一条指令执行时间不同。
随门电路层数增加,由于门延迟,位数多、计算复杂指令需执行更久。

不同指令执行时间不同,但要让所有指令都在一个时钟周期内完成,只好把时钟周期和执行时间最长的那个指令一样。不然就会导致快速执行完成的指令,需等待满一个时钟周期,才能执行下一条指令。

虽然CPI能够保持在1,但时钟频率却没法太高。太高,有些复杂指令没法在一个时钟周期内完成。在下个时钟周期到来,开始执行下条指令时,前一条指令执行结果可能还没写入寄存器。下一条指令读取的数据就不准确了。

  • 前一条指令的写入,在后一条指令的读取之前
    具有指令流水线结构的cpu_cpu流水线技术
    一个CPU时钟周期,可认为是完成一条简单指令的时间。
    为什么单指令周期处理器,反而变成执行一条最复杂的指令的时间?
    无论是Intel CPU or ARM CPU,都不是单指令周期处理器,而是采用一种叫作指令流水线(Instruction Pipeline)的技术。

现代处理器的流水线设计

指令执行过程会拆分成“取指令、译码、执行”三步。
更细分,执行的过程,还包含从寄存器或内存读数据,通过ALU运算,把结果写回寄存器或内存。

CPU的指令执行过程,其实也是由各电路模块组成:

  • 取指令时,需要译码器,把数据从内存取出来,写入寄存器

  • 指令译码时,需要另外一个译码器,把指令解析成对应控制信号、内存地址和数据

  • 指令执行时,需要一个完成计算工作的ALU。这些都是一个一个独立的组合逻辑电路,我们可以把它们看作一个团队里面的产品经理、后端工程师和客户端工程师,共同协作来完成任务。

  • 流水线执行示意图
    具有指令流水线结构的cpu_cpu流水线技术
    这就不用把时钟周期设置成整条指令执行的时间,而是拆分成完成这样的一个一个小步骤需要的时间。同时,每一个阶段的电路在完成对应的任务之后,也不需要等待整个指令执行完成,而是可以直接执行下一条指令的对应阶段。
    这样的协作模式,就是指令流水线。这里每个独立步骤,称为流水线阶段或流水线级(Pipeline Stage)。

把一个指令拆分成“取指令-指令译码-执行指令”三部分,那这就是一个三级流水线。
进一步把“执行指令”拆分成“ALU计算(指令执行)-内存访问-数据写回”,就变成一个五级流水线。
五级流水线:同一时钟周期里,同时运行五条指令的不同阶段。这时,虽然执行一条指令的时钟周期变成5,但可提高CPU的主频。
无需确保最复杂那条指令在时钟周期里执行完成,只要保障一个最复杂的流水线级操作,在一个时钟周期内完成即可。

若某一操作步骤时间太长,可考虑把该步骤拆分成更多步骤,让所有步骤需执行时间尽量差不多长。这就可解决在单指令周期处理器中遇到的,性能瓶颈来自最复杂的指令的问题。
像ARM或IntelCPU,流水线级数都已到14级。

虽然不能通过流水线,减少单条指令执行的“延时”指标,但通过同时在执行多条指令的不同阶段,提升了CPU的“吞吐率”。
外部看来,我们的CPU好像“一心多用”,同一时间,同时执行5条不同指令的不同阶段。
CPU内部,就像生产线,不同分工的组件不断处理上游传递下来的内容,而无需等待单件商品生产完成后,再启动下一件商品的生产。

超长流水线的性能瓶颈

你说流水线能增加 CPU 吞吐率,流水线级数就越深越好咯?
增加流水线深度,是有性能成本的。

同步时钟周期的,不再是指令级别,而是流水线阶段级别。
每一级流水线对应的输出,都要放到流水线寄存器(Pipeline Register),然后在下一个时钟周期,交给下一个流水线级去处理。
所以,每增加一级流水线,就要多一级写入到流水线寄存器的操作。
虽然流水线寄存器非常快,比如只有20皮秒(ps, 1 0 − 12 10^{-12} 1012秒)。
具有指令流水线结构的cpu_cpu流水线技术
但不断加深流水线,这些操作占整个指令的执行时间的比例就会不断增加。最后,性能瓶颈就会出现在这些overhead。
若指令执行有3ns=3000ps:

  • 20级流水线,则流水线寄存器写入就要400ps,占超过10%
  • 50级流水线,就要多花费1ns在流水线寄存器上,占到25%

这意味着,单纯增加流水线级数,不仅不能提升性能,反而会有更多overhead开销。所以,设计合理的流水线级数也是现代CPU中非常重要的一点。

总结

为不浪费CPU性能,通过把指令执行过程,切分成一个个流水线级,提升CPU吞吐率。而CPU设计,又是由一个个独立的组合逻辑电路串接起来形成,适合这样采用流水线“专业分工”的工作方式。

因为每一级overhead,一味地增加流水线深度,并不能无限提高性能。
因为指令的执行不再是顺序一条条执行,而是在上条执行到一半时,下一条就已经启动了,所以给程序带来很多挑战。这些挑战和对应解决方案,你就得持续关注这个系列文章了!

参考

  • 《深入理解计算机系统》的4.4章节
  • 《计算机组成与设计 硬件/软件接口》的4.5章节
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/171246.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Ubuntu15安装RabbitVCS(SVN)客户端

    Ubuntu15安装RabbitVCS(SVN)客户端Windows下常用的SVN管理工具是TortoiseSVN,而它不支持Linux。如果你想在linux下也使用同样的图形化界面来管理SVN,那么RabbitVCS是一个不错的选择。它支持和TortoiseSVN同样的操作。一、安装官方的wiki上指出了安装方法:http://wiki.rabbitvcs.org/wiki/install/ubuntu第一步

  • leetcode刷题:两数之和

    leetcode刷题:两数之和

  • 【《重构 改善既有代码的设计》学习笔记7】在对象之间搬移特性「建议收藏」

    本篇文章的内容来自《重构 改善既有代码的设计》一书学习笔记整理并且加上自己的浅显的思考总结!在对象之间搬移特性,核心就是: 决定把责任放在哪儿,重点关注责任,也就是尽量一个类之处理一类事情,或者是某个责任和这个类关系不大,就将此责任移动到关系大的类中。本篇内容两两放在一起,互相对比学习。也更方便理解和记忆。1、搬移函数(Move Method)& 搬移字段(Move field…

  • csdn-如何让你的标题比其他人的都要大

    csdn-如何让你的标题比其他人的都要大

  • 用flash做古诗动画_《古诗三首》Flash动画课件[通俗易懂]

    用flash做古诗动画_《古诗三首》Flash动画课件[通俗易懂]《古诗三首》Flash动画课件古诗词三首牧童[唐]吕岩草铺横野六七里,笛弄①晚风三四声。归来饱饭黄昏后,不脱蓑衣②卧月明。注释①弄:逗弄。②蓑衣:棕或草编的外衣,用来遮风挡雨。………舟过安仁①[宋]杨万里一叶渔船两小童,收篙②停棹③坐船中。怪生④无雨都张伞,不是遮头是使风。注释①安仁:县名。在湖南省东南部,宋时设县。②篙:撑船用的竹竿或木杆。③棹:船桨。④怪生:怪不得。……

  • linux命令杀掉进程_shell脚本获取进程号并杀死进程

    linux命令杀掉进程_shell脚本获取进程号并杀死进程1.查找需要kill掉的线程:ps-elf|grep【线程关键信息】比如:ps-elf|grepjava这样找到所有JAVA线程比如要删除tomcat线程,可以执行:ps-elf|greptomcat这样就可以找到跟tomcat相关的所有线程,从中找到你需要kill掉的线程ID2.强制终止线程:kill-9【线程ID】比如你的线程ID是5645646,那就可以执行:kill-95645646【特殊用法】kill-STOP[pid]发..

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号