存储器系统是一个具有不同容量、成本和访问时间的存储设备的层次结构。存储器层次结构是可行的,是因为与下一个更低层次的存储设备相比来说,一个编写良好的程序倾向于更频繁的访问某一个层次上的存储设备。靠近CPU的小的、快速的高速缓存存储器(cache memory)作为一部分存储在相对慢速的主存储器(mainmemory,简称主存)中的数据和 指令的缓冲区域。主存暂时存放存储在容量较大的、慢速磁盘上的数据,而这些磁盘常常又作为存储在通过网络连接的其他机器的磁盘或磁带上的数据的缓冲区域。
固态硬盘(SSD)是一种基于闪存的存储技术。一个SSD包由一个或多个闪存芯片和闪存翻译层组成,闪存芯片替代传统旋转磁盘中的机械驱动器,而闪存翻译是一个硬件/固件设备,扮演与磁盘控制器相同的角色,将对逻辑块的请求翻译成对底层物理设备的访问。
对于取指令来说,循环有好的时间和空间局部性。循环体越小,循环迭代次数越多,局部性越好。
一般而言,从高层往底层走,存储设备变得更慢、更便宜和更大。
一般而言,高速缓存是一个小而快速的存储设备,它作为存储在更大也更慢的存储设备中的数据对象的缓冲区域。使用高速缓存的过程称为缓存。 数据块总是以块大小为传送单位(transfer unit)在第k层和第k+1层之间来回拷贝。
缓存命中:当程序需要第k+1层的某个数据对象d时,它首先在当前存储在k层的一个块中查找d。如果d刚好缓存在k层,那么就“命中”。 缓存不命中:如果k层没有缓存数据对象d,那么就“不命中”。当发生缓存不命中后,第k层的缓存从第k+1层缓存中取出包含d的那个块。 冷不命中冲突不命中
早期计算机系统的存储结构只有三层:CPU寄存器、DRAM主存储器和磁盘存储。不过,由于CPU和主存之间逐渐增大的距离,系统设计者被迫在CPU寄存器文件和主存之间插入了一个小的SRAM高速缓存存储器,称为L1高速缓存。随着CPU和主存之间的性能差距不断增大,系统设计者在L1高速缓存更大的高速缓存,称为L2高速缓存。有些现代计算机还包括一个更大的高速缓存,称为L3缓存。
一般而言,高速缓存的结构可以用元组(S,E,B,m)来描述。高速缓存的大小(或容量)C指的是所有块的大小的和。标记位和有效位不包括在内。因此,C=S * E * B。根据E(每个组的高速缓存行数)高速缓存被分为不同的类: 直接映射高速缓存 每个组只有一行(E=1)的高速缓存称为直接映射高速缓存(direct-mapped cache)。组选择行匹配字选择行替换组相联高速缓存:直接映射高速缓存中冲突不命中造成的问题是源于每个组只有一行这个限制,组相联高速缓存放松了这条限制,所以每个组都保存多余一个的高速缓存行。全相联高速缓存:一个全相联高速缓存是由一个包含所有高速缓存行的组(即E=C/B)组成的。有关写的问题 设我们要写一个已经缓存了的字w写命中(write hit)。在高速 缓存更新了它的w的拷贝之后,想要更新w在层次结构中紧接着低一层中的拷贝,可以有多种选择: 直写(write-through):立即将w的高速缓存块写回到紧接着的低一层中。写回(write-back),尽可能地推迟存储器更新,只有当替换算法要驱逐更新过的块时,才把它写到紧接着的低一层中。另一个问题是如何处理写不命中。 写分配(write-allocate),加载相应的低一 层中的块到高速缓存中,然后更新这个高速缓存块。写分配试图利用写的空间局部性,但是缺点是每次不命中都会导致一个块从低一层传送到高速缓存。非写分配(not-write-allocate),避开高速缓存,直接把这个字写到低一层中。直写高速缓存通常是非写分配的。写回高速缓存通常是写分配的。一般而言,高速缓存越往下层,越可能采用写回而不是直写。实际上,高速缓存既可以保存数据也可以保存指令。只保存指令的高速缓存称为i-cache,只保存程序数据的高速缓存称为d-cache。记保存数据又保存指令的高速缓存称为统一的高速缓存(unified cache)。
在每一个循环内部缓存不命中的数量最小。
以下我会列出对我来说耗费时间较长的习题,套公式计算的题就简写了。 习题6.1
本题的要点是理解DRAM芯片的组成原理: 传统的DRAM芯片单元被分成d个超单元,每个超单元由w个DRAM单元组成。一个dxW的DRAM总共存储了dw位信息。一个16x8的DRAM芯片组织如下图所示:
x前面的数字代表超单元的数量, 其分割应趋向于正方形,才能使得访问第(i, j)个地址时,访问的地址位数趋于最少。 br和bc是寻址时需要的位数,4=2^2,16=2^4以此类推,完成填表。 习题6.2
磁盘容量=(字节数/扇区) * (平均盘区数/磁道) * (磁道数/表面) * (表面数/盘片) * (盘片数/磁盘) 计算磁盘容量:2个盘片,10000个柱面,每条磁道平均400个扇区,每个扇区有512个字节。 (注:每个盘片有2个表面,柱面是所有盘片表面上到主轴中心的距离相等的磁道的集合。) 磁盘容量=(512) * (400) * (10000) * (2) * (2)=8 192 000 000字节=8.192 GB习题6.3
一个有如下参数的磁盘:旋转速率:15000 RPM,T(avg seek)=8ms,每条磁道的平均扇区数:500 平均旋转时间:T(avg rotation)=1/2 * T(max rotation) =1/2 * (60sec/15000 RPM) * (1000ms/sec) =2 ms 平均传送时间:T(avg transfer)=(60s/15000 RPM) * (1/500) * (1000ms/sec)=0.008 ms T(access)=T(avg seek) + T(avg rotation) + T(avg transfer) = 8 + 2 + 0.008=10 ms习题6.4
首先,T(avg seek)= 5 ms, T(max rotation) = 6 ms, T(avg rotation) = 3 ms A:总时间为T(avg seek) + T(avg rotation) + 2 * T(max rotation) = 5 + 3 + 12= 20 ms B:总时间为(T(avg seek) + T(avg rotation) ) * 2000 = =16 000 ms习题6.5
A:(10 ^ 9 * 128) * (1/470) * (1/(86400 * 365)) 约为8年 B:(10 ^ 9 * 128) * (1/303) * (1/(86400 * 365)) 约为13年 C:(10 ^ 9 * 128) * (1/20000) * (1/365)约为17535年习题6.7
需要保证最内层循环对应数组的最细元素。 int sumarray3d(int a[N][N][N]){ int i,j,k,sum=0; for(i=0;i<N;i++) for(j=0;j<N;j++) for(k=0;k<N;k++) sum+=a[i][j][k]; return sum; }习题6.8
clear1函数以步长为1的引用模式访问数组,空间局部性最好。习题6.9
其实也是套公式计算 C = B * E * S b = log2(B) s = log2(S) t = m - (s + b)习题6.10
命中率3/4习题6.11
A:每个连续的数组片由2 ^ t个块组成。 数组头2 ^ t个连续的块都会映射到组0,接下来的映射到1. B:对于直接映射高速缓存(S, E, B, m)=(512, 1, 32, 32),数组的头2 ^ 18个块会被映射到组0,接下来的映射到组1。习题6.12
习题6.13 地址:0x0E34 A. 地址格式:
B.内存引用:
习题6.14 地址:0x0DD5 A. 地址格式:
B.内存引用:
习题6.15 地址:0x01FF4 A. 地址格式:
B.内存引用:
习题6.16
组3包含一个有效行,标记为0x32,组中只有一个有效行,4个地址会命中。 在组3中命中的4个十六进制地址是: 0x064C 0x064D 0x064E 0x064F习题6.17
注意:每个高速缓存行只包含数组的一个行,高速缓存正好只够保存一个数组。对于所有的i,src和dst的行i映射到同一个高速缓存行。 对dst[0][0]写会驱逐当我们读src[0][0]时加载进来的那一行。当读src[0][1]是,会有一个不命中。 当高速缓存为32字节时,他足够容纳两个数组。所有的不命中都是开始时的;冷不命中。习题6.18
A:读的总数:512 B:缓存不命中的读总数:256 C:不命中率:256/512=1/2习题6.19
这个高速缓存只能保存数组的一半。所以,按照列顺序来扫描数组的第二部分时会驱逐扫描第一部分时加载进来的那些行。 A:读的总数:512 B:缓存不命中的读总数:256 C:不命中率:256/512=1/2 D:如果高速缓存足够大,那么它能够保存整个数组,所有的不命中都会是开始时的冷不命中,而不命中率1/4。习题6.20
该循环步长为1,因此所有的不命中都是最开始时的冷不命中。 A:读的总数:512 B:缓存不命中的读总数:128 C:不命中率:128/512=1/4 D:冷不命中不可避免,命中率不变。习题6.21
周期:2670 / 6500 * 8 = 3.2周期 4周期在这个程序中,变量sum和i在每次循环时就被引用一次,因此对sum和i来说,有较好的时间局部性。 对变量array来说,它是一个int类型数组,循环时按顺序访问array,因为一个数组在内存中是占用连续的内存空间。因而的较好的空间局部性。 这个程序具有良好的空间和时间局部性。 再看一个二维数组的例子:
int sum2(int array[M][N]) { int i, j, sum = 0; for(i = 0; i < M; i++){ for(j = 0; j < N; j++) sum += array[j][i]; } return sum; }这个相比之前的程序局部性就不好了,尤其是空间局部性。 当M=2,N=3时, 访问这个数组的时候,从array[0][0]开始,array[1][0]->array[2][0]->array[0][1]->array[1][1]… 数组在内存中是按行顺序来存放的,array[0][0]的地址假设为0x0,array[0][1]地址应该是0x4,array[0][2]地址0x8……这样的程序对array[0][0]、array[0][1]元素的访问顺序就变成了1、3、5、2、4、6,步长变成了3而不是最优的1。但这个程序是可以变成步长为1的最优程序的,只需要修改遍历的顺序,使之按照行来扫描:
int sum2(int array[M][N]) { int i, j, sum = 0; for(i = 0; i < M; i++){ for(j = 0; j < N; j++) sum += array[i][j]; } return sum; }A. Windows 宿主机
B. Ubuntu虚拟机
C. ARM实验箱
D. 以上都不对
【答案】B
本来选了A,后来翻了翻自己的博客,发现提到了宿主机之类的,然后果断改了选项,就错了。。跟宿主机IP应该是毫无关系的,nfs系统是把Ubuntu虚拟机的一个目录映射到ARM实验箱,跟Windows机无关。
实验1中Windows宿主机,Ubuntu虚拟机,ARM实验箱三者IP要在同一网段,操作中是根据()的IP来确定网段的。A. Windows 宿主机 B. Ubuntu虚拟机 C. ARM实验箱 D. 以上都可以
【答案】C
本题我选了个D。。ARM实验箱的IP修改要重新烧录Linux系统,Windows 宿主机,Ubuntu虚拟机的IP比较容易修改,所以我们在超级终端中查看ARM实验箱的IP,之后把Windows 宿主机,Ubuntu虚拟机的IP设置成和ARM实验箱同一个网段。
计划学习时间:12小时
实际学习时间:16小时
转载于:https://www.cnblogs.com/zhuohua/p/8052213.html
