3.2《深入理解计算机系统》笔记(二)内存和高速缓存的原理【插图】

  《深入计算机系统》笔记(一)主要是讲解程序的构成、执行和控制。接下来就是运行了。我跳过了“处理器体系结构”和“优化程序性能”,这两章的笔记继续往后延迟!

    《深入计算机系统》的一个很大的用处是:给了我们很多定义式的解释,或者称之为科学的解释,这将成为我的理论依据;不再是网上一些自称老手的闲聊了。不愧是计算机最牛逼的大学卡内基-梅隆大学的教材。

    该blog跳过第四章CPU的结构,第五章优化程序性能,也没有详细讨论高速缓存的机制。

六、存储器层次结构

有必要将存储器层次结构再次列出来:

高速缓存的“行”、“块”和“组”是什么意思?参考本bolg最下面“高速缓存的物理逻辑图”

    字:一个word的意思,IA32中指的是16位,

    块:是一个固定大小的信息包,在高速缓存和主存之间来回传送。块包含32~64个字节。所以内存中只是信息,成为块

    行:高速缓存中存储块已经其他信息的容器。所以,行总是一个块的大小,通常“行”和“块”可以互换使用。结合上图高速缓存既有块和其他信息,称之为“行”

    组:是一个或者多个行

---》之前知识停留在RAM和ROM,现在再往前推进一步RAM也分为静态SRAM和动态的DRAM。SRAM主要用于高速缓存DRAM用于内存

    SRAM将每个位存储在一个双稳态的存储器单元里。每个单元是用一个六个晶体管电路来实现。它可以无限期地保持在两个不同的电压配置或状态之一。就是说只要有电,他就会永远地保持它的值。即使有干扰,例如电子噪音、扰乱电压,当干扰消除时,电路就会恢复到稳定值。下图说明了“双稳态的”效果,采用倒摆的时钟。

难道这个原理可以解释:电磁干扰造成电视画面错乱,手机信号干扰么?

DRAM将没位存储为一个电容,这个电容非常小,通常只有30毫微微法拉。与SRAM不同的是DRAM的存储单元对干扰非常敏感。当电容电压没扰乱之后,他就永远无法恢复了。所以DRAM需要不断刷新电容。暴露在光线下会导致电容电压改变。实际上,数码照相机和摄像机中的传感器本质上就是DRAM单元的阵列。【惊讶】

无论如何SRAM和DRAM都是易失的(volatile)

    下面讨论DRAM的读取机制:

    

这种二维阵列的缺点是:必须分两步发送地址,增加存储时间。

---》DDR2和DDR3的内存的区别。Double data-rate synchronous  DRAM带宽分别是4位和8位。DDR3也分为1333MHz和1600MHz

---》磁盘,略过。

---》DRAM和磁盘的性能滞后于CPU的新能,虽然他们的性能都在增长。

这也就是为什么CPU和内存之间的高速缓存一直增多。

---》人们发现无法像以前那样增大CPU的时钟频率了,计算机制造商撞上了“能量墙”因为如果那样芯片的功耗会太大。所以多核就出现了,多核出现后CPU的时钟有所减少,并区域平缓。但是有效CPU周期时间还是像之前的速率增长。

---》高速缓存运行机制。p(406)

    

---》缓冲区命中。

    为什么第二次启动程序要比第一次快的多,就是因为缓冲区命中的原理。第一次启动后很多数据还停留在多级缓冲区中,这个时候如果再次启动就会减少数据移动次数,也就减少程序的启动时间。从上图中我们发现,有部分数据存在与高速缓存中,就不用从内存中取了。

    举例子:灌溉小麦,使用100米的水渠(普通水渠,不是水泥那种),假如水泵出水是固定的。

    第一次使用时,水渠中的水前进很慢,走完100米的水渠大约需要10分钟,这是因为:有一些水会损失掉,即被渗到水渠下面的泥土中了。这部分水可以看作是“高级缓存”中的水。

    第二次(时间较短)再灌溉小麦时,水渠的水走的很快,花费了2分钟,因为相对于第一次来说,水渠不需要王下面渗很多水了。如果时间长了,隔了2天,水渠中的渗的水再往下渗。

    第三次灌溉(时间较长),同样需要一些水渗到水渠下泥土里面,所以,还是需要10分钟。

    用计算机中的实例:当一条加载指令指示CPU从内存地址A读出一个字时,他将地址A发送给高速缓存。如果高速缓存证保存着A处的地址的按个拷贝,它就立即将那个字发给CPU。这要比从内存中读取快很多。

---》core i7的高速缓存层次结构

注意:只保存指令的高速缓存i-cache,只保存数据的高速缓存叫d-cache。既保存指令又保存数据的成为统一的高速缓存。

就像第一章说的那样高速缓存至关重要,特别是“缓冲区命中”这个技术如果优化好了,速度将会很大改进。

高速缓存的物理逻辑图:

    

 

---》直接映射高速缓存p(410)

根据E(高速缓存行)高速缓存被分为不同的类。每个组只有一行(E=1)的高速缓存呗称为直接映射高速缓存    虽然一个整形可能在寄存器中,而整形数组,则可能存在与高速缓存中。

---》冲突不命中。请看下面的例子:

 

[cpp] view plain copy
 
  1. float dotprod(float x[8], float y[8])  
  2. {  
  3.     float sum = 0.0;  
  4.     int i;  
  5.     for(i = 0;i < 8;i++)  
  6.         sum += x[i] * y[i];  
  7.     return sum;  
  8. }  

当第一次迭代x[0]时,必定不命中,那么会导致x[0]~x[3]的块被加载到高速缓冲组0,下一次是y[0]的调用,又一次不命中,导致y[0]~y[3]的块被拷贝到组0,从而覆盖前一次x的值。如此迭代,下次x[1]的值继续不命中,继而将x[0]~x[3],覆盖调y[0]~y[3]的值。这种就叫做冲突不命中,也叫”抖动“。本质原因是:x和y数组被映射到同一个组。程序员可以避开这种抖动,但是我觉得编译器应该解决这个问题。

 

 

原书中可能错误的地方不算多,但也影响到阅读的心情。

p406图6-24少了一个10的单元格,12单元格重复

p403图6-21 a)函数名字应该为:int sumarraycol(int a[m][n]).

p199第一行最后应该为“偏移量”

posted @ 2017-09-15 10:44  瘋耔  阅读(418)  评论(0编辑  收藏  举报
跳至侧栏