当前位置: 首页 > 内存管理 > 正文

内存管理器(十九)存储器层次结构

前言

这两天看了《CSAPP》的第6章,主要讲的是存储器层次结构,环顾内存管理器系列的文档,发现确实没有一个终结性的小结内存管理体系的东西,所以这次正好借着小结读书笔记的机会正好总结。

存储器层次结构概况

我认为计算机的两个比较重要的问题,一个是运算,一个是存储。其实图灵最早的设计也是如此,我也学习学习伟人的思想。存储器系统其实是一个根据容量,速度,成本,访问时间,读取时间,效率等等根据不同特点的不同部分的一个复杂的体系。

举个例子:

L0 : 寄存器

L1 : L1高速缓存

L2 : L2高速缓存

L3 : L3高速缓存

L4 : 主存(内存条)

L5 : 本地磁盘

L6 : 分布式文件系统, Web等

以上简单说明了7个级别的存储结构,从上到下成本更低,体积更大,速度越慢。

随机访问存储器

静态RAM

SRAM(CPU 的高速缓存) ,将每个位存储在一个双稳态的存储器单元里面。每个单元是用一个六晶体管,只要有电就可以工作,即使受到干扰,当干扰结束的时候,它依然会恢复到之前的值。

动态RAM

DRAM (主存) ,将每一位存储为对一个电容充电,但是这个存储器会收到干扰,并且不能长时间的保持数据存在,但是计算机运行的时钟周期是以纳秒来衡量的,存储系统必须周期性的读出数据刷新内存条。

传统的DRAM

DRAM 芯片中的单元被分成d个超单元,,每个单元由W个DRAM 单元组成。一个d*w的DRAM 总共存储dw位信息。

这个是存储器是通过引脚来确定来传送行和列的值,然后通过数据总线传出传入数据。

SSD

闪存基于EEPROM 是一类非易失性存储器,它已经在我们的生活中很常见了,比如U盘,SSD固态应硬盘,速度确实提高了不少,但是寿命有限,根据写的次数增多,很多存储块逐渐的被损坏。

关于地址与数据的交互

这里记载一个《CSAPP》的例子好了。

movl A ,%eax

地址A的内容首先被加载到寄存器%eax中,CPU芯片称为总线接口,首先CPU 把地址A放到系统总线上I/O桥将信号传递到存储器总线,其次主存收到地址总线上的信号,从存储器总线读取地址,从DRAM取出数字,并将数据写到存储器总线。I/O桥将存储器总线信号翻译成系统总线信号,然后沿着系统总线传输,最后CPU 得到信号。从系统总线上读取数据,并将数据拷贝到寄存器。

存储器层次结构中的缓存

一般而言,高速缓存是一个小而快速的存储设备,它作为存储在更大也更慢的设备中的数据对象的缓冲区域。使用高速缓存的过程称为缓存。

数据总是以块大小为传递单元,在相邻的层次之间来回拷贝,但是在每一个层次之中的数据块的大小是固定的,应该是统一数据块大小可以增加访问速率的原因。

缓存的命中与不命中

如果需要查找一个数据的时候,首先在这个缓存中查找信息,如果找到信息就是缓存命中,如果没有找到就是缓存未命中,当缓存未命中后,程序就需要从数据存储相应的存储结构得到数据然后拷贝 到缓存中来,此时相应的上一级存储结构就会被替换,替换的数据块称为“牺牲块”,至于如何找出“牺牲”块,其中由一个相应的替换策略。这个策略有很多种可能的实现方式。

类型                              缓存什么                       被缓存在何处                     延迟(周期)                           由谁管理

CPU寄存器                    4/8B                             芯片的CPU寄存器                    0                                             编译器

TLB                              地址翻译(旁路缓冲区)   芯片上的TLB                      0                                            硬件MMU

L1                                64字节块                           芯片上的L1高速缓存              1                                             硬件

L2                               64字节块                           芯片上/下的L2高速缓存         10                                          硬件

L3                              64字节块                            芯片上/下的L3高速缓存         30                                           硬件

虚拟存储器              4KB页                                  主存                                           100                                         硬件+os

缓冲区缓存              部分地址空间                      主存                                           100                                         os

磁盘缓存                   磁盘扇区                             磁盘控制器                               100 000                                 控制器固件

网络缓存                  部分文件                              本地磁盘                                   10 000 000                     AFS/NFS 客户

浏览器缓存              Web 页                                 本地磁盘                                   10 000 000                       Web 浏览器

Web 缓存                 Web 页                                 远程服务器磁盘                        1 000 000 000              Web 代理服务器

AFS : 安德鲁文件系统

 

局部性原理

局部性原理在很多地方都有“拯救”程序的意义,这里简单说下。一般使用使用局部性好的程序都倾向于访问程序频繁访问的内存位置,更或者说倾向于使用已经访问的临近的数据项。这是一个持久性的概念,对于硬件和软件都有很重要的意义。

局部性主要表现在两个方面:时间局部性,空间局部性。跟直接的说局部性原理其实就是尽最大的可能引用缓存,减少寻址的时间,减少寻址动作可以减少很多事情的,减少寻址动作就是减少了页错误,减少中断,减少数据拷贝。所以说一个有良好局部性的程序比局部性差的程序运行的更快。

对程序数据引用的局部性,举个例子,比如一个二维数组求和


int sum(int a[M][N]){

int i,j;

int sum = 0;

for(i  = 0;i < M;i++){                        /*这样其实就是利用了局部性,如果两重循环为 先N 后M则就没有使用好局部性*/

for(j = 0;j < N;j++){

sum += a[i][j];

}

}

return sum;

}



还有取指令的局部性,因为指令也是存储在寄存器中的,CPU必须取出这些指令,所以像使用循环这种指令,当循环体比较小的时候,程序的局部性会非常的好。

 

高速缓存存储器

早期