存储器层次结构

随机访问存储器 RAM
  • 静态RAM 常用作Cache
  • 动态RAM DRAM会因为泄漏电流各种因素在10~100毫秒失去电荷,但计算机运行是在纳秒级别。存储器系统会周期性读出再写入来刷新存储位,有些系统使用额外的位来提供纠错码,硬件级纠错。
DRAM的一种二维阵列组织

在这里插入图片描述
二维阵列组织读取,先接收行地址,将其对应行拷贝到内部行缓冲区,接收列地址,从缓冲区拷贝对就列单元发送至存储控制器。

磁盘以扇区大小的块来读写数据。对扇区的访问时间( access time)有三个主要的部分:寻道时间( seek time)、旋转时间(rotational latency〉和传送时间( transfer time ):

  • 寻道时间
  • 旋转时间:分最大旋转时间与平均时间,平均为max一半
  • 传送时间:旋转时间 / 每圈磁道的扇区数

在这里插入图片描述
一般而言,层次结构中较低层(离CPU较远〉的设备的访问时间较长,因此为了补偿这些较长的访问时间,倾向于使用较大的块。

缓存

  程序通常是按照一系列阶段(例如,循环)来运行的,每个阶段访问缓存块的某个相对稳定不变的集合。例如,一个嵌套的循环可能会反复地访问同一个数组的元素。这个块的集合被称为这个阶段的工作集( working set)。当工作集的大小超过缓存的大小时,缓存会经历缓存不命中(capacitymiss)。换句话说,缓存就是太小了,不能处理这个工作集。

  一个空的缓存有时被称为冷缓存(cold cache),此类不命中被称为强制性不命中(compulsory miss)或冷不命中(cold miss)。这通常是短哲的事件,不会在稳定状态中出现,稳定状态指的就是在反复的存储器访问已经将缓存变暖( warmed up〉了之后。

  冲突不命中(conflict miss),缓存太小,有些转换策略会使缓存一直不命中。

高速缓存映射

当高速缓存确定一个请求命中时,抽取出被请求的字的过程,分为三步:①组选:②行匹配:③字拾取。

在这里插入图片描述
用中间位来索引更好:为了提高高速缓存的效率(在一个拥有较好空间局部性的程序中,可能只访问第一组缓存),使存入的数组相邻的的块总是存入不同的高速缓存行上。

术语"抖动"(thrash)描述的是这样一种情况,其中高速缓存反复地加载和驱逐高速缓存块相同的组。来回存储x和y的内容的块,导致冲突不命中。

  • 直接映射高速缓存

  • 组相联高速缓存:这时有组内行替换策略。例如,最不常使用( least-frequently-used,LFU)策略会替换在过去某个时间窗口内引用次数最少的那―行;最近最少使用(least-recently-used,LRU)策略会替最后一次访问时间最久远的那一行。所有这些策略都需要额外的时间和硬件。但是,越往存储器层次结构下面走,远离CPU,一次不命中的开销就会更加昂贵,用更好的替换策略使得不命中最少也变得更加值得了。

  • 块相相关高速缓存:因为高速缓存电路必须并行地搜索许多相匹配的标记,构造一个又大又快的相联高速缓存很困难,而且很昂贵。因此,全相联高速缓存只适合做小的高速缓存,例如虚拟存储器系统中的翻译备用缓冲器(TLB),它缓存页表项。

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

写相关

假设CPU写一个已经缓存了的字 w [写命中( write hit)]。在高速缓存更新了它的w的拷贝之后,更新w在存储器中的拷贝

  1. 最简单的方法,称为直写( write-through),就是立即将w的高速缓存块写回到存储器中。虽然简单,但是直写的缺点是每条存储指令都会引起总线上的一个写事务。
  2. 另一种方法,称为写回( write-back),尽可能地推迟存储器更新,只有当替换算法要驱逐己更新的块时,才把它写到存储器。由于局部性,写回能显著地减少总线事务的数量,但是它的缺点是增加了复杂性。高速缓存必须为每个高速缓存行维护一个额外的修改位(dirty bit),表明这个高速缓存块是否被修改过。

写不命中

  1. 一种方法,称为写分配( write-alocate),加载相应的存储器块到高速缓存中,然后更新这个高速缓存块。写分配试图利用写的空间局部性,但是缺点是每次不命中都会导致一个块从存储器传送到高速缓存。写回高速缓存通常是写分配的。
  2. 另一种方法,称为非写分配( not-write-allocate ),避开高速缓存,直接把这个字写到存储器中。直写高速缓存通常是非写分配的。

通常,由于较长的传送时间,存储器层次结构中较低层的缓存更可能使用写回,而不是真写。例如,虚拟存储器系统(用主存作为存储在磁盘上的块的缓存)只使用写回。

高速缓存既保存数据,也保存指令。只保存指令的高速缓存称为i-cache。只保存程序数据的高速缓存称为d-cache。既保存指令又包括数据的高速缓存称为统一的高速缓存(unified cache)。一个典型的桌面系统CPU芯片本身就包括一个L1 i-cache和个L1 d-cache

在这里插入图片描述

性能影响分析
  • 高速缓存大小的影响
    一方面,较大的高速缓存可能会提高命中率。另一方面,使得大存储器运行得更快总是要难一些的。结果,较大的高速缓存可能会增加命中时间。对于芯片上的 Ll高速缓存来说这一点尤为重要,因为它的命中时间必须为一个时钟周期。

  • 块大小的影响
    大的块有利有弊。一方面,较大的块能利用程序中可能存在的空间局部性,帮助提高命中率。不过,对于给定的高速缓存大小,块越大就意味着高速缓存行数越少,这会损害时间局部性比空间局部性更好的程序中的命中率。较大的块对不命中处罚也有负面影响,因为块越大,传送时间就越长。现代系统通常会折中,使高速缓存块包含4~8个字。

  • 相联度的影响
    较高的相联度(也就是E的值较大)的优点是降低了高速缓存由于冲突不命中出现抖动的可能性。较高的相联度会增加命中时间,因为复杂性增加了.另外,还会增加不命中处罚,因为选择牺牲行( victim line)的复杂性也增加了。

  • 写策略的影响
    直写高速缓存比较容易实现,而且能使用写缓冲区(write buffer),它独立于高速缓存,用来更新存储器。此外,读不命巾开销没这么大,因为它们不会触发存储器写。另一方面,写回高速缓存引起的传送比较少,它允许更多的到存储器的带宽用于执行DMA的IO没备。此外,越往层次结构下面走,传送时间增加,减少传送的数量就变得更加重要。一般而言,高速缓存越往下坛,越可能使用写回而不是直写。

存储器山

步长轴方向表示为空间局部性斜坡,为读取数组内容的循环步长
工作集轴方向表示为时间局部性斜坡,因为是不同的缓冲级别
在这里插入图片描述

实验代码
wget http://csapp.cs.cmu.edu/3e/mountain.tar

tar -xvf mountain.tar
cd mountain/

./mountain > text.txt

实验中cpu数据

[tom@tom-virtual-machine ~]$lscpu
Architecture:          x86_64
CPU 运行模式:    32-bit, 64-bit
CPU MHz:             2808.000
L1d 缓存:          32K
L1i 缓存:          32K
L2 缓存:           256K
L3 缓存:           6144K
...
[root@tom-virtual-machine ~]#cat /proc/cpuinfo
model name      : Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
...
AB型	sum += A[i][k] * B[k][j];    步长1扫描A的一行(因为在最外循环i固定,k切分); 以步长n扫描B的一列(列j固定,k取n行)
	(ijk)
	       for (i = 0; i < n; i++)
	            for (j = 0; j< n; j++){
	                sum = 0.0 ;.
	                for (k = 0 ; k < n; k++)
	                    sum += A[i][k] * B[k][j];
	                c[i][j] += sum;
	            }
	(jik)
	        for (j = 0; j< n; j++)
	            for (i = 0; i < n; i++){
	                sum = 0.0 ;.
	                for (k = 0 ; k < n; k++)
	                    sum += A[i][k] * B[k][j];
	                c[i][j] += sum;
	            }
AC型	 c[i][j] += A[i][k]*r;       步长n扫描A的列(因为在最内循环列j固定,i取n行); 以步长n扫描C的列
	 (jki)           
	        for (j= 0; j < n; j++)
	            for (k = 0 ; k < n; k++ ) {
	                r = B[k][j];
	                for (i = 0; i < n; i++ )
	                    c[i][j] += A[i][k]*r;
	            }
	(kji)            
	        for (k = 0 ; k < n; k++ )
	            for (j= 0; j < n; j++){
	                r = B[k][j];
	                for (i = 0; i < n; i++ )
	                    c[i][j] += A[i][k]*r;
	            }
BC型	c[i][j] += r*B[k][j];	步长1扫描B的列(因为在最外循环k固定,j切分); 以步长1扫描c的列
	(kij)
	        for (k = 0; k < n; k++)
	            for (i = 0; i < n; i++ ) {
	                r = A[i][k];
	                for (j = 0; j < n; j++)
	                    c[i][j] += r*B[k][j];
	            }
	(ikj)            
	        for (i = 0; i < n; i++ )
	            for (k = 0; k < n; k++){
	                r = A[i][k];
	                for (j = 0; j < n; j++)
	                    c[i][j] += r*B[k][j];
	            }

假设只能存数组的四个内容
在这里插入图片描述

  • 注意高速缓存不命中率并不是问题的全部,存储器访问的数量也很重要,需在二者中权衡,来达到最优性能。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值