深入理解计算机系统读书笔记二

内存映射I/O技术

CPU使用内存映射I/O技术来向I/O设备发射命令。在使用内存映射I/O的系统中,地址空间中有一块地址是为了与I/O设备通信保留的。每个这样的地址称为I/O端口。当一个设备连接到总线时,它被映射到一个或多个端口。通过内存映射I/O技术将I/O设备放置到内存空间而不是I/O空间,使得访问系统设备和访问内存一样,简化了程序设计的难度和接口的复杂性。

直接内存访问(DMA)

设备可以字节执行读或写总线事务而不需要CPU干涉的过程,称为直接内存访问,这种数据传送被称为DMA传送。

为什么SSD随机写比随机读慢

efXZPP.png
数据是以页为单位进行读写的。只有在一页所属的块整个被擦出后才能写。随机写的速度慢有两方面的原因。首先擦除块需要相对较长的时间,比访问页的的时间一般会高出一个数量级。另以方面,如果试图写的页所属的块中包含其它数据,就必须将块中带有数据的页复制到一个已经擦除的块中,然后再将块进行擦除然后写入数据页。显然,这会耗费很多时间。为了解决这个问题,制造商再内存翻译层中实现了复杂的逻辑,最小化内部写的次数,但是随即写的性能也很难与随机读一样好。

局部性

一个编写良好的程序常常具有良好的局部性,他们更加倾向于应用临近于其它最近引用过的数据项的数据项,或者最近引用过的数据项的本身。这种倾向性被称为局部性原理。

时间局部性

再一个良好时间局部性的程序中,被引用过一次的内存位置很可能再不远的将来再被多次引用

空间局部性

在一个具有良好的空间局部性的程序中,如果一个内存位置被引用过一次,那么程序很可能在不远的将来引用附近的一个内存位置。

利用局部性我们能做什么

1.局部性原理允许计算机设计者通过引入称为高数缓存存储器的小而快速的存储器来保存最近被引用的指令和数据项,从而提高对主存的访问效率
2.一般而言,有良好的局部性的程序比局部性差的程序运行得更快.(比如在遍历二位数组时按列扫描的效率比按行扫描低很多)

存储器层次结构中的缓存

高速缓存(cache)四一个小而快速的存储设备,它作为存储在更大、也更慢的设备中的数据对象的缓存区域。使用高速缓存的过程被称为缓存。
ehCgDf.png
对于每个k,位于k层的更快更小的存储设备作为位于k+1层的更大更慢的存储设备的缓存。存储器被划分成连续的数据对象块(chunk),称为块(block)。数据总是以块大小为传送单位在第k层和第k+1层之间来回复制的。

缓存命中

当程序需要第k+1层的某个数据对象d时,它首先在当前存储在第k层的一个块中查找d。如果d刚好缓存在第k层中,那么就说缓存命中(cache hit)。

缓存不命中

如果第k层中没有缓存数据对象d,那么就是我们说说的缓存不命中(cache miss)。当发生缓存不命中时,第k层的缓存从第k+1层缓存中取出包含d的那个块,如果第k层的缓存已经满了,就会覆盖现存的一个块。覆盖一个现存的块的过程被称为替换或驱逐这个块。被驱逐的这个块也被称为牺牲块。常用的替换策略有随机替换策略和最近最少被使用替换策略(LRU)。

缓存不命中的种类

1.如果缓存是空的,那么对任何数据对象的访问都不能被命中,一个空的缓存被称为冷缓存,此类不命中称为强制性不命中或冷不命中。这种缓存不命中是非常短暂的,缓存暖身后将进入稳定状态。
2.冲突不命中。前面也提到,缓存是以块为单位进行存储的,这些块再缓存中需要遵循一些放置策略。一种是k+1层中任何块可以放置到k层中的任何块,这中方式实现起来成本昂贵(因为定位起来代价很高)。所以,还有一种放置策略将块根据一定的规则映射到指定的位置(类似与hash),那么显然就会存在冲突的情况,这个时候,缓存的空间可能还是有空闲的,但是因为存在放置位置的冲突而使得一些块被覆盖,而出现冲突不命中。
3.容量不命中。程序运行时所需的工作集大于缓存容量,造成缓存不得刷出一些块,所造成的缓存不命中称为容量不命中。

ebcqhT.png

高速缓存存储器

高速缓存存储器的存在是为了解决CPu寄存器,DRAM主存储器之间速度的巨大差异。系统设计者再CPU和主存之间插入一块SRAM高速缓存存储器,称为L1高数缓存(一级缓存)。访问L1高速缓存只需要4个时钟周期,几乎和访问寄存器一样快。后来又设计了L2高速缓存和L3高速缓存。

通用的高数缓存存储器组织结构

计算机中将高速缓存组织为高速缓存组,每个组包含E个高速缓存行。每个行由有效位,标记位和数据块组成。
eb4Vv8.png

直接映射高速缓存

根据每个组的高速缓存行的行数,将高速缓存分为不同的类,每个组只有一行的高数缓存倍称为直接映射高速缓存(direct-mapped cache)

组选择

直接映射高速缓存从待缓存的数据的地址中取出一部分,将这些位解释位一个对应的组号。
evZXGT.png

行匹配

行匹配对于直接映射高速缓存非常简单,因为直接映射高速缓存的每个组只有一行。待缓存的数据w的地址的一部分也被解释为标记,如果该缓存行的标记位的值与数据w解释出的标记相等,那么该缓存行中包含该数据的一个副本。
evm1B9.png

字选择

字选择也很简单,确定了缓存行,将数据w的地址中的一段解释为偏移量,如果将高数缓存看成一行数组的话,那么偏移量就相当于索引。

直接映射高速缓存中的冲突不命中

float dotprod(float x[8],float y[8])
{
    float sum=0.0;
    int i;
    for(int i=0;i<8;i++)
    {
        sum+=x[i]+y[i];
    }
    
    return sum;
}

这个函数具有良好的空间局部性。但如果x[i]和y[i]被映射到相同的高速缓存组中,那么在运行时,会出现冲突不命中。高速缓存会反复地加载和驱逐相同的高速缓存块的组。

组相联高速缓存

在组相联高速缓存(set associative cache)中每个组都保存有多于一个的高速缓存行。
ev8ehj.png

全相联高速缓存

全相联高速缓存(fully associative cache)是由一个包含所有高速缓存行的组组成的,
ev8Y4J.png
全相联高速缓存只适合左小的高速缓存,例如虚拟内存系统中的翻译备用缓冲器(TLB),它缓存也表项。

posted @ 2019-09-01 22:07  zofun  阅读(506)  评论(0编辑  收藏  举报