指令集是CPU体系架构的重要组成部分。C语言的语法是对解决现实问题的运算和流程的方法的高度概况和抽象,其主要为算术、逻辑运算和分支控制,而指令集就是对这些抽象的详细支持,汇编仅仅只是是为了让开发者更好地记住指令,但它跟CPU所认的机器码事实上是一一相应的,因此汇编也是低级语言。

CPU的指令运行一般包含取指、译码和运行,这是经典的三级指令运行流水线,教科书上往往以这三种过程来描写叙述,arm7也是。可是现代的CPU设计往往使用更广泛使用的5级流水线,也就是分为取指、译码、运行、訪存和回写。为什么要分为5级?这是由流水线的各个阶段的时间来决定的。我们能够考虑现实生活的工厂的流水线。

如果某流水线仅仅有 三个工序,有三个工人A、B、C,则这条生产线的效率就取决于效率最低的那个工人的效率。现如果B做完其负责的工序须要10秒,而A和C完毕仅仅须要5秒,总共要完毕4个产品。那总时间应该是:5+10*4+5 = 50秒,(第一个5是A先做第一道工序的时间,这时B和C都得等,而最后一个5是C必须要等B所有完毕后才干開始)即会出现C在等待,而B一直在忙死忙活的场景。

当然,不管如何,流水线的运行总比完毕没有流水好,就好比A、B、C负责的工作都由一个人去做,那做完一个得20秒。所有做完得20*4 = 80秒。

最理性的场景就是三个人做事的效率是一样的,那就不会出现等待的情况。那如今确实遇到B工作效率最低的问题,怎么解决呢?就是将B的工作又一次分解,平均分成两个工序,也就是B1和B2,分别都是5秒完毕,那完毕的总时间是40秒。

CPU指令的三级流水运行正是遇到各步骤流水时间不均的问题,也就是取指和译码往往比較快,而运行包含运算和訪问寄存器、内存或者回写等功能,因此运行的时间一般比取指和译码要长,取指和译码能够在单时钟周期内完毕,但运行须要2到3个时钟周期才干完毕。要想得到更高的流水效率,就须要将运行部分分解为运行(运算等)、訪存(内存)和回写(寄存器)。

CPU指令的流水线运行对于软件开发者来说,最重要的就是要知道当前PC(程序计数寄存器)的值与当前运行指令的关系。取指指的是CPU依据当前PC的值内存的相应地址去取指令,因此PC值永远都指的都是当前取指令步骤的地址,而译码则是CPU的一部分电路依据取出来的指令机器码进行译码,选择相应的电路来运行这条运行,如选择加法电路还是减法电路,还是逻辑与电路等等;运行就是这个电路的运行过程了。

arm7的流水线示意图是:

从图能够看到在T1时刻,CPU的运行电路运行的是MOV指令,而取指电路取的是SUB指令,因此当前运行电路的MOV相应的运行地址应该是当前PC值减8. 假设当前运行的指令是一个函数调用(即BL指令),但返回地址就应该是ADD指令所在的地址,即(PC减4)。

有人问到流水线断流的问题,补充说明一下,断流主要有下面情况:

1)数据相关。如第二条指令须要的数据正好是第一条指令运行的结果。这时第二条必须等待。

2)分支跳转。指令分支推断之后,可能会顺序运行,也可能跳转到其它地方,这时也会引起流水线的断流。

CPU指令的流水线运行的更多相关文章

  1. 四十年前的 6502 CPU 指令翻译成 JS 代码会是怎样

    去年折腾的一个东西,之前 blog 里也写过,不过那时边琢磨边写,所以比较杂乱,现在简单完整地讲解一下. 前言 当时看到一本虚拟机相关的书,正好又在想 JS 混淆相关的事,无意中冒出个问题:能不能把某 ...

  2. Java内存模型一个经典例子-指令重排序与CPU指令多发射导致执行结果异常

    先上代码: import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; ...

  3. 一文彻底搞懂CAS实现原理 & 深入到CPU指令

    本文导读: 前言 如何保障线程安全 CAS原理剖析 CPU如何保证原子操作 解密CAS底层指令 小结 朋友,文章优先发布公众号,如果你愿意,可否扫文末二维码关注下? 前言 日常编码过程中,基本不会直接 ...

  4. 从 Java 代码到 CPU 指令

    从 Java 代码到 CPU 指令 我们都知道,编写的 Java 代码,最终还是要转化为 CPU 指令才能执行的.为了理解 Java 内存模型的作用,我们首先就来回顾一下从 Java 代码到最终执行的 ...

  5. 深入设计电子计算器(一)——CPU指令集设计

    版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/8254096.html 作者:窗户 Q ...

  6. Computer Science 学习第四章--CPU 指令集和指令处理

    Instruction set Y86 指令集 运算符:addl, subl, andl, and xorl 跳转符:jmp,jle,jl,je,jne,jge, andjg 条件符:cmovle, ...

  7. CPU设计学习-流水线

    各种名词 标量流水线 超级流水线 超标量流水线与多发射技术 经典五级流水线 IF |Instruction Fetch,取指 ID |Instruction Decode,译码 EX |Execute ...

  8. CPU指令、机器码、程序和汇编语言

    一.指令 指令就是指挥机器工作的指示和命令.控制器靠指令指挥机器工作,人们用指令表达自己的意图,并交给控制器执行.一台计算机所能执行的各种不同指令的全体,叫做计算机的指令系统或指令集,每一台计算机均有 ...

  9. cpu指令重排序的原理

    目录: 1.重排序场景 2.追根溯源 3.缓存一致性协议 4.重排序原因 一.重排序场景 class ResortDemo { int a = 0; boolean flag = false; pub ...

随机推荐

  1. .Net之一般处理程序

    1.一般处理程序是什么? 答:一般处理程序是以.ashx结尾的文件,默认命名为Handler1.ashx. 用在Web项目中,也就是我们常说的网站项目. 2.新建一个一般处理程序 1.1 新建一个空网 ...

  2. iOS:ABPeoplePickerNavigationController系统通讯录使用

    昨天因项目需求要访问系统通讯录获取电话号码,于是乎从一无所知,开始倒腾,倒腾了一下午,总算了弄好了.写这边博客是为了记录一下,自己下一次弄的时候就别在出错了.同时,有和我一样的菜鸟能够避免走一下弯路. ...

  3. 从零开始写驱动——vfd专用驱动芯片HT16514并行驱动程序编写

    前言 一直看别人搞的 vfd 很漂亮,前段时间淘了个 vfd 模块来,但没有模块资料,还好芯片没有打磨的,良心商家啊.周末抽空来研究一下这个东西. 从零开始 打开外壳 测试线路 查看芯片是 HT165 ...

  4. 一道试题引发的血案 int *ptr2=(int *)((int)a+1);

    某日,看到一道比较恶心的C语言的试题,考了很多比较绕的知识点,嘴脸如下: int main(void) { int a[4] = {1, 2, 3, 4}; int *ptr1=(int *)(&am ...

  5. MSSQL 修改数据库的排序规则

    1.修改数据库排序规则 ALTER DATABASE [CHARACTER] COLLATE Chinese_PRC_CI_AS ; 2.修改表中列的排序规则 如果下列其中之一当前正在引用一个列,则无 ...

  6. php知识(第2天)

    运算符 PHP中运算符一共分为9类: 赋值运算符, 算术运算符,比较运算符, 逻辑运算符, 错误抑制符, 三目运算符, 位运算符, 自操作运算符, 连接操作符 算术运算符 算术运算: 基本运算符: + ...

  7. 【转】VPN服务器配置详解

    参考博文: VPN服务器配置详解   等公司上服务器开始配置 vpn

  8. ASP.net WebAPI 上传图片

    [HttpPost] public Task<Hashtable> ImgUpload() { // 检查是否是 multipart/form-data if (!Request.Cont ...

  9. Delphi函数指针的两种定义(对象方法存在一个隐藏参数self,所以不能相互赋值)

    delphi中经常见到以下两种定义 Type TMouseProc = procedure (X,Y:integer); TMouseEvent = procedure (X,Y:integer) o ...

  10. BZOJ 1192 鬼谷子的钱袋 (二进制思想)

    题解:鉴于二进制的思想来划分 #include <cstdio> int main(){ int n,d=0;scanf("%d",&n); while(1&l ...