深入浅出计算机组成原理
徐文浩
bothub创始人
立即订阅
13019 人已学习
课程目录
已完结 62 讲
0/4登录后,你可以任选4讲全文学习。
入门篇 (5讲)
开篇词 | 为什么你需要学习计算机组成原理?
免费
01 | 冯·诺依曼体系结构:计算机组成的金字塔
02 | 给你一张知识地图,计算机组成原理应该这么学
03 | 通过你的CPU主频,我们来谈谈“性能”究竟是什么?
04 | 穿越功耗墙,我们该从哪些方面提升“性能”?
原理篇:指令和运算 (12讲)
05 | 计算机指令:让我们试试用纸带编程
06 | 指令跳转:原来if...else就是goto
07 | 函数调用:为什么会发生stack overflow?
08 | ELF和静态链接:为什么程序无法同时在Linux和Windows下运行?
09 | 程序装载:“640K内存”真的不够用么?
10 | 动态链接:程序内部的“共享单车”
11 | 二进制编码:“手持两把锟斤拷,口中疾呼烫烫烫”?
12 | 理解电路:从电报机到门电路,我们如何做到“千里传信”?
13 | 加法器:如何像搭乐高一样搭电路(上)?
14 | 乘法器:如何像搭乐高一样搭电路(下)?
15 | 浮点数和定点数(上):怎么用有限的Bit表示尽可能多的信息?
16 | 浮点数和定点数(下):深入理解浮点数到底有什么用?
原理篇:处理器 (18讲)
17 | 建立数据通路(上):指令+运算=CPU
18 | 建立数据通路(中):指令+运算=CPU
19 | 建立数据通路(下):指令+运算=CPU
20 | 面向流水线的指令设计(上):一心多用的现代CPU
21 | 面向流水线的指令设计(下):奔腾4是怎么失败的?
22 | 冒险和预测(一):hazard是“危”也是“机”
23 | 冒险和预测(二):流水线里的接力赛
24 | 冒险和预测(三):CPU里的“线程池”
25 | 冒险和预测(四):今天下雨了,明天还会下雨么?
26 | Superscalar和VLIW:如何让CPU的吞吐率超过1?
27 | SIMD:如何加速矩阵乘法?
28 | 异常和中断:程序出错了怎么办?
29 | CISC和RISC:为什么手机芯片都是ARM?
30 | GPU(上):为什么玩游戏需要使用GPU?
31 | GPU(下):为什么深度学习需要使用GPU?
32 | FPGA和ASIC:计算机体系结构的黄金时代
33 | 解读TPU:设计和拆解一块ASIC芯片
34 | 理解虚拟机:你在云上拿到的计算机是什么样的?
原理篇:存储与I/O系统 (17讲)
35 | 存储器层次结构全景:数据存储的大金字塔长什么样?
36 | 局部性原理:数据库性能跟不上,加个缓存就好了?
37 | 高速缓存(上):“4毫秒”究竟值多少钱?
38 | 高速缓存(下):你确定你的数据更新了么?
39 | MESI协议:如何让多核CPU的高速缓存保持一致?
40 | 理解内存(上):虚拟内存和内存保护是什么?
41 | 理解内存(下):解析TLB和内存保护
42 | 总线:计算机内部的高速公路
43 | 输入输出设备:我们并不是只能用灯泡显示“0”和“1”
44 | 理解IO_WAIT:I/O性能到底是怎么回事儿?
45 | 机械硬盘:Google早期用过的“黑科技”
46 | SSD硬盘(上):如何完成性能优化的KPI?
47 | SSD硬盘(下):如何完成性能优化的KPI?
48 | DMA:为什么Kafka这么快?
49 | 数据完整性(上):硬件坏了怎么办?
50 | 数据完整性(下):如何还原犯罪现场?
51 | 分布式计算:如果所有人的大脑都联网会怎样?
应用篇 (5讲)
52 | 设计大型DMP系统(上):MongoDB并不是什么灵丹妙药
53 | 设计大型DMP系统(下):SSD拯救了所有的DBA
54 | 理解Disruptor(上):带你体会CPU高速缓存的风驰电掣
55 | 理解Disruptor(下):不需要换挡和踩刹车的CPU,有多快?
结束语 | 知也无涯,愿你也享受发现的乐趣
免费
答疑与加餐 (5讲)
特别加餐 | 我在2019年F8大会的两日见闻录
FAQ第一期 | 学与不学,知识就在那里,不如就先学好了
用户故事 | 赵文海:怕什么真理无穷,进一寸有一寸的欢喜
FAQ第二期 | 世界上第一个编程语言是怎么来的?
特别加餐 | 我的一天怎么过?
深入浅出计算机组成原理
登录|注册

22 | 冒险和预测(一):hazard是“危”也是“机”

徐文浩 2019-06-14
过去两讲,我为你讲解了流水线设计 CPU 所需要的基本概念。接下来,我们一起来看看,要想通过流水线设计来提升 CPU 的吞吐率,我们需要冒哪些风险。
任何一本讲解 CPU 的流水线设计的教科书,都会提到流水线设计需要解决的三大冒险,分别是结构冒险(Structural Hazard)、数据冒险(Data Hazard)以及控制冒险(Control Hazard)。
这三大冒险的名字很有意思,它们都叫作 hazard(冒险)。喜欢玩游戏的话,你应该知道一个著名的游戏,生化危机,英文名就叫 Biohazard。的确,hazard 还有一个意思就是“危机”。那为什么在流水线设计里,hazard 没有翻译成“危机”,而是要叫“冒险”呢?
在 CPU 的流水线设计里,固然我们会遇到各种“危险”情况,使得流水线里的下一条指令不能正常运行。但是,我们其实还是通过“抢跑”的方式,“冒险”拿到了一个提升指令吞吐率的机会。流水线架构的 CPU,是我们主动进行的冒险选择。我们期望能够通过冒险带来更高的回报,所以,这不是无奈之下的应对之举,自然也算不上什么危机了。
事实上,对于各种冒险可能造成的问题,我们其实都准备好了应对的方案。这一讲里,我们先从结构冒险和数据冒险说起,一起来看看这些冒险及其对应的应对方案。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《深入浅出计算机组成原理》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(22)

  • 易儿易
    一路纵队,前边有人停下系鞋带,后边所有人都得原地踏步踏,不然就得踩着脑袋过去了……
    2019-06-15
    1
    10
  • -W.LI-
    先写后读:数据依赖,读依赖于之前的写正常的依赖关系所以叫数据依赖。
    先读后写:反依赖,要保证读到写之前的数据,与正常的相反叫反依赖。
    写完再写:输出依赖。两次写操作顺序反了的话输出就错了。所以叫输出依赖。
    记不住不晓得这么理解可以么
    2019-06-23
    4
  • 瀚海星尘
    因为如果前一个指令插入nop后一个指令不插,那么当前指令被延迟执行的阶段就会和下一个指令的统一阶段在同一个周期内一起执行,而这是电路结构不允许的,统一阶段同一周期只能有单一输入。
    2019-07-26
    1
  • Geek_54edc1
    在当前指令插入nop可能会对后续指令造成新的依赖,干脆后面的指令也加上nop操作,要等就一起等
    2019-06-29
    1
  • Hommin
    CPU虽然可以同时执行多条流水线,但需要保证在一个时钟周期中同一个阶段只能有一条流水线在执行(如,可以是执行流水线A的取值阶段和流水线B的译码阶段,但不能是A的取值阶段和B的取值阶段)。那么当前指令插入一个NOP操作后,该操作的后续阶段往后移,而后续指令的对应阶段也必须往后移动,防止出现在一个时刻执行两个相同的阶段。
    我的问题是,这种对应添加NOP操作,一定会后续某个时刻消除掉吧。是不是当某一条指令没有该阶段的时候消除掉的?
    2019-11-25
  • prader
    计算机里面,(为了快去处理数据,采用了一些设计方式),冒险分为,数据冒险和结构冒险和控制冒险。
      结构冒险的解决办法,是把高速缓存分为指令缓存和数据缓存。
      数据冒险(因为程序存在,数据依赖,读依赖,输出依赖),解决办法是,流水线冒泡。
    2019-09-22
  • 记忆犹存
    计算机硬件和软件最常用的思想:增加一个中间层。

    作者回复: 没错,不过这个思路其实也是软件架构慢慢容易“腐化”的原因。随着中间层变多,系统的复杂度和熵在增加,如果没有精心维护,容易最后变成一个难以维护的代码库。

    2019-09-10
  • 活的潇洒
    “现在终于知道公司的程序员同事人手一部不同规格的机械键盘了的原因了”

    day22 笔记:https://www.cnblogs.com/luoahong/p/11436264.html
    2019-09-01
  • J.D.
    这种插入“空操作”的思想,我觉得挺有意思,就像一些加密算法,限定了输入数据的长度,那么就可以使用填充 0 来补充长度。
    2019-07-26
  • -W.LI-
    老师好:高速缓存分两个了。取指令的寄存器等硬件都是两份了是么?
    2019-06-23
  • 焰火
    浩哥问您两个问题哈 ~~
    ①结构冒险的解决方案,采用高速缓存法的意思是:因为高缓的访问速度快,事先将内存中的指令读入高缓中,然后CPU可以在一个时钟周期内完成两个(或更多)的高缓中的指令,就相当于cpu在一个时钟周期内对原内存数据完成了多次的操作么?

    ②如果写的程序中有个循环一连串的读写读写数据操作,有可能造成流水线停顿过多,从而退化成一级流水线,如果真有这样的代码,我们该如何修改呢?
    2019-06-16
  • cc
    流水线模式下,一条指令被拆分成n个阶段。这样的好处是增加吞吐量,所谓吞吐量,简单理解就是我们程序中的并发,可以有多条指令同时在CPU里执行不同的阶段,不同阶段,不同阶段。
    但需要重点强调的是,不是并行:对于指令执行的某一具体的阶段,还是串行的。为什么?我的理解是针对单一阶段,比如解码,电路是唯一的,不同的指令输入不尽相同,为了不出错,串行是最保险的。
    回到老师的问题,如果后边的指令,不加NOP,那也就意味着有相同的指令准备执行相同阶段,因为串行,还是需要等待的。不如加NOP更简单明了。
    2019-06-16
  • Only now
    应该是为了维持指令执行的步调
    2019-06-15
  • humor
    因为在判断当前指令是否有数据冒险的判断依据里 并没有之前指令是否有NOP操作,只有后续指令插入了对应的NOP操作后判断才可能是正确的。
    2019-06-14
  • coder
    用了这么久的HHKB都不知道普通键盘还有锁键的问题🌚🌚🌚
    2019-06-14
  • haer
    所有后续指令也要插入对应的 NOP 操作,这是为什么呢?

    我想是这样:就像两个人以相同的速度一前一后向前走,前面的人停下,后面的人也停下,两个人的距离保持不变,且前面的人一直在前面,后面的人一直在后面。这样的话指令一定是顺序执行的。
    2019-06-14
  • 云开
    老师:结构冒险的解决方案是把高速缓存拆分成指令缓存和数据缓存。是不是意味着同一个时钟周期两条指令同时都取内存的数据而不是一个取数据一个取指令就不会发生冲突?
    2019-06-14
  • Linuxer
    我们不仅要在当前指令里面,插入 NOP 操作,所有后续指令也要插入对应的 NOP 操作,这是为什么呢?我想是为了实现简单吧,要不下面的指令都得检查与上面每一条当前指令为nop的后面的非nop指令是不是有数据依赖。
    2019-06-14
  • 陈华应
    如果内存地址 b 的指令在内存地址 4 的指令之后写入。
        老师这个是b在4之前才是先写在写有问题吧?对后续程序来说 a=2应该才是正确的吧
    2019-06-14
  • MJ
    【题外话】老师,是否了解中型企业关于安全的架构,一般怎么做,有没有好的推荐参考?最近做这事比较急。
    2019-06-14
收起评论
22
返回
顶部