深入浅出计算机组成原理
徐文浩
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第二期 | 世界上第一个编程语言是怎么来的?
特别加餐 | 我的一天怎么过?
深入浅出计算机组成原理
登录|注册

39 | MESI协议:如何让多核CPU的高速缓存保持一致?

徐文浩 2019-07-24
你平时用的电脑,应该都是多核的 CPU。多核 CPU 有很多好处,其中最重要的一个就是,它使得我们在不能提升 CPU 的主频之后,找到了另一种提升 CPU 吞吐率的办法。
不知道上一讲的内容你还记得多少?上一节,我们讲到,多核 CPU 里的每一个 CPU 核,都有独立的属于自己的 L1 Cache 和 L2 Cache。多个 CPU 之间,只是共用 L3 Cache 和主内存。
我们说,CPU Cache 解决的是内存访问速度和 CPU 的速度差距太大的问题。而多核 CPU 提供的是,在主频难以提升的时候,通过增加 CPU 核心来提升 CPU 的吞吐率的办法。我们把多核和 CPU Cache 两者一结合,就给我们带来了一个新的挑战。因为 CPU 的每个核各有各的缓存,互相之间的操作又是各自独立的,就会带来缓存一致性(Cache Coherence)的问题。

缓存一致性问题

那什么是缓存一致性呢?我们拿一个有两个核心的 CPU,来看一下。你可以看这里这张图,我们结合图来说。
在这两个 CPU 核心里,1 号核心要写一个数据到内存里。这个怎么理解呢?我拿一个例子来给你解释。
比方说,iPhone 降价了,我们要把 iPhone 最新的价格更新到内存里。为了性能问题,它采用了上一讲我们说的写回策略,先把数据写入到 L2 Cache 里面,然后把 Cache Block 标记成脏的。这个时候,数据其实并没有被同步到 L3 Cache 或者主内存里。1 号核心希望在这个 Cache Block 要被交换出去的时候,数据才写入到主内存里。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《深入浅出计算机组成原理》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(19)

  • 炎发灼眼
    老师,有个问题,如果说一个核心更新了数据,广播失效操作和地址,其他核心的缓存被更新为失效,那更新数据的那个核心什么时候把数据再次写入内存呢,按照上一讲,在下次更新数据的时候才会写入,那如果在这个之间,别的核心需要用到这部分数据,看到失效,还是从内存读,这不是还是读不到最新的数据么。
    2019-07-26
    8
    14
  • bro.
    Java中volatile变量修饰的共享变量在进行写操作时候会多出一行汇编**
        ```
        0x01a3de1d:movb $0×0,0×1104800(%esi);0x01a3de24:lock addl $0×0,(%esp);
        ```
    lock前缀的指令在多核处理器下会:
            1. 将当前处理器缓存行的数据写回到系统内存
            2. 这个写回内存的操作会使其他CPU里缓存了改内存地址的数据无效
    多处理器总线嗅探:
            1. 为了提高处理速度,处理器不直接和内存进行通信,而是先将系统内存的数据读到内部缓存后在进行操作,但**写回操作**不知道这个更改何时回写到内存
            2. 但是对变量使用volatile进行写操作时,JVM就会向处理器发送一条lock前缀的指令,将这个变量所在的缓存行的数据写回到系统内存
            3. 在多处理器中,为了保证各个处理器的缓存一致性,每个处理器通过嗅探在总线上传播的数据来检查自己的缓存值是不是过期了,如果处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置为无效状态,就相当于**写回时发现状态标识为0失效**,当这个处理器对数据进行修改操作时,会重新从系统内存中读取数据到CPU缓存中
    2019-07-31
    5
  • 许童童
    MSI 缓存一致性协议没有E这个状态,也就是没有独享的状态。
    如果块尚未被装入缓存(处于“I”状态),则在装入该块之前,必须先要保证该地址的数据不会在其他缓存的缓存块中处于“M”状态。如果另一个缓存中有处于“M”状态的块,则它必须将数据写回后备存储,并回到“S”状态。
    MESI 多了E状态(独享状态),如果当前写入的是E,则可直接写入,提高了性能。
    2019-07-24
    5
  • 林三杠
    涉及到数据一致性的问题,cpu层,单机多线程内存层,分布式系统多台机器层,处理办法都差不多,原理是相通的
    2019-07-24
    5
  • casper
    原文中这一段有一点疑问。
    【那么“独占”和“共享”这两个状态的差别在哪里呢?这个差别就在于,在独占状态下,对应的 Cache Line 只加载到了当前 CPU 核所拥有的 Cache 里。其他的 CPU 核,并没有加载对应的数据到自己的 Cache 里。这个时候,如果要向独占的 Cache Block 写入数据,我们可以自由地写入数据,而不需要告知其他 CPU 核。】
    如果CPU A是在独占状态下使用某数据X,这时CPA更新了CacheBlock中的数据X为X1,而并不用通知其他CPU核。并且,CPU A的CacheBlock此时是脏的,但是根据上一讲写回的原理,X1并没有写回内存。
    这时CPU B中的指令也要用到X的,CPU B势必会从内存读取到其Cache Block,而CPU B使用的值就是X,和 CPU A使用中X1不就不一致了吗?
    2019-11-27
  • 追风筝的人
    MESI 协议,是已修改、独占、共享以及已失效这四个缩写的合称。独占和共享状态,就好像我们在多线程应用开发里面的读写锁机制,确保了我们的缓存一致性。
    2019-11-18
  • 拯救地球好累
    请问下老师,总线嗅探的话,各CPU会在每个指令周期中安排一次嗅探吗?
    2019-10-30
  • 随心而至
    老师这种讲课方式,真赞。每节只讲少量知识点,后面的知识点将前面的知识点作为基础,并解决前面提出的疑问。
    2019-10-22
  • 随心而至
    我编译了volatile相关的代码,在Win10 64位下,将java代码转换成字节码,再转换成机器码,发现是由lock cmpxchg两个指令实现的。
    2019-10-22
  • 活的潇洒
    1、有人成功,有人普通,到底是什么原因导致的?

    我们想成功,我们个人的水平必须是足够高的

    2、那么我们的水平高来源于哪里?

    来源于我们获得的知识,生活中每一天工作、上班、路上、回家获取的信息

    day39 笔记:https://www.cnblogs.com/luoahong/p/11358997.html
    2019-08-21
  • 小美
    关于更新的数据什么时候写回内存的问题,看那个状态图,应该是总线发出读或者写请求的时候,这个数据就会写回,然后进去共享或者失效状态。
    2019-08-15
  • 靠人品去赢
    其实想知道,那种一个主板插两个CPU那种服务器主板,他是怎么搞得?L3缓存会打通吗,还是就是两台电脑共用一个主板而已。
    2019-07-30
  • 逍遥法外
    老师你好,关于MESI,有一个疑问:MESI协议是不是只能保证缓存的最终一致?不然为什么java会有volatile?
    2019-07-25
    1
  • W.jyao
    没明白,其他cpu收到写失效之后把自己的cache置位失效状态,然后还做其他什么处理吗?
    2019-07-25
    1
  • Sentry
    L1,2,3 cache,以及主存都是公用的一个虚拟地址空间吗?感觉可以把cache里的地址和主存地址串起来用,每次读写都是唯一的地址值,这样是不是就可以避免缓存失效?
    2019-07-25
    2
  • 一塌糊涂
    老师问个问题,锁总线,锁缓存中中的锁缓存的概念,锁缓存用了mesi协议,cpu还做其他的了吗?还是单纯只靠缓存一致性,来锁缓存,
    2019-07-24
  • 一塌糊涂
    通俗易懂,找了很多书,缓存讲的最好的。缓存一致性,内存一致性也讲讲吧,
    2019-07-24
  • xindoo
    cpu,多线程,分布式系统解决一致性问题的方法还是很类似的
    2019-07-24
  • AaronLee
    第二次看到MESI协议,老师写的简单易懂
    2019-07-24
    1
收起评论
19
返回
顶部