第八周(10.26-11.01):
学习计时:共10小时 读书:5 代码:1 作业:2 博客:2 |
一、学习目标 |
复习前面Linux 命令,Linux 编程基础,教材前七章内容 |
二、学习资源 |
1. 教材 2.答案解析见http://group.cnblogs.com/topic/73060.html 考试中错的最多的会再考,关注一下排名前十的同学做错的题目
|
三、学习方法 |
1. 进度很重要:必须跟上每周的进度,阅读,练习,问答,项目。我会认真对待每一位同学,请你不要因为困难半途而废。 2. 问答很重要:遇到知识难点请多多提问,这是你的权利更是您对自己负责的义务。问答到博客园讨论小组:http://group.cnblogs.com/103791/ 3. 实践很重要:解决书中习题,实践书中实例,完成每周项目,才算真的消化了这本好书。通过实验楼环境或自己安装的虚拟机在实践中进行学习 4. 实验报告很重要:详细记录你完成项目任务的思路,获得老师点评和帮助自己复习。学习完成后在博客园中(http://www.cnblogs.com/)把学习过程通过博客发表,博客标题"信息安全系统设计基础第八周期中总结"
|
四、学习任务 |
1. 复习Linux命令,特别是man -k, cheat, grep -nr xxx /usr/include 2. 复习vi, gcc, gdb,make的使用 3. 复习教材内容ch01 ch02 ch03 ch04 ch06 ch07 4. 复习前面的考题(答案解析见http://group.cnblogs.com/topic/73060.html) ,下次考试考每次考试错的最多的题目 5. 期中总结发一篇Blog: 知识点总结 自己的收获(不要假大空) 自己的不足(要具体,有改进措施) 课程建议和意见(要有理由)
|
五、后续学习预告(可选): |
第十章:系统级I/O |
六、学习过程 |
复看了前期学过的知识和做的博客园笔记,顺带看了之前实验的步骤和知识,然后看了习题,还有做过的家庭作业。 翻看了做错的测试题,看看到底是什么原因做错的。 |
七、遇到的问题及解决 |
(提示:此处由学生填写,是重要的得分点,要写出遇到的问题和解决方案以及对出现问题的思考)
对过去知识的遗忘和重温,貌似是很难的事情,毕竟不是学的很扎实。 不管是家庭作业还是测试题,看完之后好像很陌生的样子。
|
八、其他 |
(提示:此处由学生填写,灵感,领悟等) |
深入理解计算机系统期中总结
第二周内容总结:
Unix命令行操作
1).重要快捷键:
[Tab]:使用Tab键来进行命令补全
[Ctrl+c]:强行终止当前程序
其他一些常用快捷键
按键 |
作用 |
Ctrl+d |
键盘输入结束或退出终端 |
Ctrl+s |
暂定当前程序,暂停后按下任意键恢复运行 |
Ctrl+z |
将当前程序放到后台运行,恢复到前台为命令fg |
Ctrl+a |
将光标移至输入行头,相当于Home键 |
Ctrl+e |
将光标移至输入行末,相当于End键 |
Ctrl+k |
删除从光标所在位置到行末 |
Alt+Backspace |
向前删除一个单词 |
Shift+PgUp |
将终端显示向上滚动 |
Shift+PgDn |
将终端显示向下滚动 |
2).利用历史输入命令
使用键盘上的方向上键,恢复你之前输入过的命令
3).使用通配符
星号(*)和问号(?),用来对对字符串进行模糊匹配(比如文件名,参数名)。当查找文件夹时,可以使用它来代替一个或多个真正字符;当不知道真正字符或者懒得输入完整名字时,常常使用通配符代替一个或多个真正的字符。
Shell 常用通配符:
字符 |
含义 |
* |
匹配 0 或多个字符 |
? |
匹配任意一个字符 |
[list] |
匹配 list 中的任意单一字符 |
[!list] |
匹配 除list 中的任意单一字符以外的字符 |
[c1-c2] |
匹配 c1-c2 中的任意单一字符 如:[0-9] [a-z] |
{string1,string2,...} |
匹配 sring1 或 string2 (或更多)其一字符串 |
{c2..c2} |
匹配 c1-c2 中全部字符 如{1..10} |
4).在命令行中获取帮助
使用man 命令
区段 |
说明 |
1 |
一般命令 |
2 |
系统调用 |
3 |
库函数,涵盖了C标准函数库 |
4 |
特殊文件(通常是/dev中的设备)和驱动程序 |
5 |
文件格式和约定 |
6 |
游戏和屏保 |
7 |
杂项 |
8 |
系统管理命令和守护进程 |
要查看相应区段的内容,就在 man 后面加上相应区段的数字即可
在 man 中使用搜索,/<你要搜索的关键字>,查找到后你可以使用n键切换到下一个关键字所在处,shift+n为上一个关键字所在处。使用Space(空格键)翻页,Enter(回车键)向下滚动一行,或者使用j,k(vim编辑器的移动键)进行向前向后滚动一行。按下h键为显示使用帮助(因为man使用less作为阅读器,实为less工具的帮助),按下q退出。
Linux 下的账户管理的基础知识
who 命令其它常用参数
参数 |
说明 |
-a |
打印能打印的全部 |
-d |
打印死掉的进程 |
-m |
同am i,mom likes |
-q |
打印当前登录用户数及用户名 |
-u |
打印当前登录用户登录信息 |
-r |
打印运行等级 |
创建用户需要 root 权限,这里就要用到 sudo 这个命令了。不过使用这个命令有两个大前提,一是你要知道当前登录用户的密码,二是当前用户必须在 sudo 用户组。退出当前用户跟退出终端一样可以使用 exit 命令或者使用快捷键 Ctrl+d。
方法一:使用groups命令
方法二:查看/etc/group文件
这里 cat 命令用于读取指定文件的内容并打印到终端输出,后面会详细讲它的使用。 | sort 表示将读取的文本进行一个字典排序再输出
/etc/group 的内容包括用户组(Group)、用户组口令、GID 及该用户组所包含的用户(User),每个用户组一条记录。
二、Linux 文件权限
绝对路径
关于绝对路径,简单地说就是以根"/"目录为起点的完整路径,以你所要到的目录为终点
相对路径
相对路径,也就是相对于你当前的目录的路径,相对路径是以当前目录 . 为起点,以你所要到的目录为终点,表现形式如: usr/local/bin
1.新建
新建空白文件
$ cd ~
$ touch test
新建目录
使用 mkdir(make directories)命令可以创建一个空目录,也可同时指定创建目录的权限属性
2.复制
复制文件
使用cp(copy)命令复制一个文件或目录到指定目录。
复制目录
如果直接使用cp命令,复制一个目录的话
3.删除
删除文件
使用rm(remove files or directories)命令,删除一个文件或目录
忽略这提示,直接删除文件,可以使用-f参数强制删除:
$ rm -f test
删除目录
跟复制目录一样,要删除一个目录,也需要加上-r或-R参数:
$ rm -r family
4.移动文件与文件重命名
移动文件
使用mv(move or rename files)命令,移动文件(剪切)。将文件"file1"移动到"Documents"目录mv 源目录文件 目的目录:
$ mv file1 Documents
重命名文件
将文件"file1"重命名为"myfile" mv 旧的文件名 新的文件名:
$ mv file1 myfile
批量重命名
专业的命令rename来实现
5.查看文件
使用cat,tac和nl命令查看文件
使用more和less命令分页查看文件
使用head和tail命令查看文件
6.查看文件类型
7.编辑文件
第三周内容总结:
1 Linux命令
ls命令,ls或ls .显示是当前目录的内容,这里"."就是参数,表示当前目录,是缺省的可以省略。我们可以用ls -a .显示当前目录中的所有内容,包括隐藏文件和目录。
2 man命令
我们可以通过man man来查看man的帮助
grep 命令和管道,可以多关键字查找:
man -k key1 | grep key2 | grep key3 | ...
3 cheat 命令
4 其他核心命令
和查找相关的核心命令还有find,locate,grep,whereis,which,其中:
find查找一个文件在系统中的什么位置,locate是神速版本的find(Windows下有个Everything工具和locate类似).
grep 可以对文件全文检索,支持正则表达式,正则表达式也是一个重要的元知识。
whereis,which告诉你使用的命令工具装在什么地方。
5 VIMTUTOR
第四周内容总结:
笔记:
1.三种数字:无符号数、有符号数(2进制补码)、浮点数,信息安全系同学从逆向角度考虑为什么会产生漏洞
无符号数:基于传统的二进制表示法,表示大于或者等于零的数字。
补码:表示有符号整数最常见的方法,可以为正可以为负。
浮点数:表示实数的科学计数法。
结果太大可能会使得某些运算溢出,大量的计算机安全漏洞是由于计算机算术运算的微妙细节引发的。
2. 进制转换,注意拿二进制作中间结果就好转了
四位二进制等于一位十六进制,2的n次幂换算十六进制,
3. gcc -m32 可以在64位机上生成32位的代码
4. 字节顺序是网络编程的基础,记住小端是"高对高、低对低",大端与之相反就可以了。
小端法:最低有效字节在最前面的方式
大端法:最高有效字节在最前面的方式
也有双端法。
已知,Linux 32、 Windows、Linux 64是小端法机器。Sun是大端法机器。
5. p28的代码,使用强制类型转换来访问和打印不同程序对象的字节表示。
6. 能区分逻辑运算(结果是1或0)和位运算(结果是位向量),所有逻辑运算都可以用与、或、非表达(最大式、最小式),而与或非可以用"与非"或"或非"表达,所以,只要一个与非门,就可以完成所有的逻辑运算。使用掩码,利用位向量来对集合编码。掩码是位运算的重要应用,对特定位可以置一,可以清零。
7. 要用C99中的"long long"类型,编译是要用 gcc -std=c99,C语言定义了每种数据类型必须能够表示的最小的取值范围。C和C++都支持有符号和无符号数,JAVA只支持有符号数。
8. 补码的利用寄存器的长度是固定的特性简化数学运算。类似于钟表,12-1 等价于 12 + 11,利用补码可以把数学运算统一成加法,只要一个加法器就可以实现所有的数学运算。对于某些程序来说,用某个确定大小的表示来编码数据类型非常重要,比如Java标准非常明确,采用补码表示,单字节数据类型成为byte而不是char且没有long long数据类型。因此保证了Java程序在无论什么机器上都能表现得一样。
9. 有符号数还有两种标准的表示方法:反码和原码。C语言允许在各种不同的数字数据类型之间做强制类型转换,且支持所有整型数据类型的有符号和无符号运算,通常大多数数字都默认为有符号的。注意C语言中有符号数和无符号数的转换规则,位向量不变。信息就是"位+上下文"。
10.怎么样让负数等于正数? 信息安全的逆向思维
利用printf首先将一个字当做一个无符号数输出,然后再把它当做一个有符号数输出。转换的原则是底层的位表示保持不变。就是应用函数U2TW,将无符号数转换为有符号数。
11. 0扩展和符号扩展
0扩展:将一个无符号数转换为一个更大的数据类型,在表示的开头添加0.
符号扩展:将一个补码数字转换为一个更大的数据类型。
12. 深入思考一下代码和结果
当参数length为0时,程序代码会出错,说明从有符号数到无符号数的隐式强制类型转换很容易引发错误。由于length在代码中是无符号的,0-1将会进行无符号计算,就会等价于MOD算法,相当于得到一个MAX数值,所以所有数都是小于等于MAX值的,于是总是为真。所以代码尝试访问数组a的非法元素。
13. p54: 如何让整数运算溢出?如何避免?
首先,无符号数运算:所有无符号数运算都是以2的n次方为模,(n是结果中的位数)。所以它不存在运算时的没有那种所谓的"溢出",当它超过范围时,从零开始重新计数!当一个无符号数和有符号数相加的时候,有符号数会自动转化为无符号数参与运算!
其次,有符号数运算: 是可能发生"溢出"的,而且溢出的结果是未定义的。当一个运算的结果发生溢出时,做出任何假设都是不安全的。
14. p62 XDR库中的安全漏洞
参数过大,第10行上的乘法运算会溢出,从第16行开始的循环会试图复制所有字节,超出已分配的缓冲区的界限,从而破坏其他的数据结构,导致程序崩溃或者行为异常。可见malloc使用了一个32位无符号数作为参数,因此不可能分配一个大于232个字节的块,所以没必要,应该将其放弃,返回一个NULL。
15.关于整数运算的最后思考
计算机执行的"整数"运算实际上是一种MOD运算形式,表示数字的有限字长限制了可能的值的取值范围,导致运算结果溢出。补码提供了一种既能表示负数又能表示整数的灵活方法。C语言中某些规定可能会产生出乎意料的结果,而且难以察觉,unsigned
数据类型概念上简单,却可能导致很多意想不到的行为。
16. 浮点数有科学计数法的基础就不难理解,IEEE标准754
17.浮点数运算的不精确性与舍入
二进制表示法只能表示那些能够被写成x*2y的数,其它的值只能被近似表示。增加二进制的表示长度可以提高表示的精度。
18. IEEE浮点标准,float/double类型
IEEE浮点标准用V=(-1)S*M*2E的形式来表示一个数:符号s决定正负,对于数值0的符号位解释作为特殊情况处理。尾数M是一个二进制小数。阶码E作用是对浮点数加权,权重是2的E次幂。
浮点数的位划分三个字段,分别对这些值进行编码:
一个单独的符号位s直接编码符号s
K位的阶码字段编码阶段E
N位小数字段编码尾数M
两种最常见的格式就是float 和double,区分一下单精度和双精度的具体情况。
19.整数与浮点数表示同一个数字的关系:相关的区域对应整数的低位,刚好在等于1的最高有效位之前停止,也就是隐含的开头的位1,与浮点数表示的小数部分的高位时相匹配的。
20.整数与浮点数转换规则
第五周内容总结:
X86 寻址方式经历三代:
1 DOS时代的平坦模式,不区分用户空间和内核空间,很不安全
2 8086的分段模式
3 IA32的带保护模式的平坦模式
Intel与ATT格式的不同
每个指令类都有对字节、字和双字数据进行操作的指令。分为四组:加载有效地址,一元操作,二元操作,移位。
条件码
CF:进位标志,最近的操作使得最高位产生了进位。用于检查无符号操作数的溢出。
ZF:零标志。最近的操作得出结果为0。
SF:符号标志。最近的操作得到的结果为负数。
OF:溢出标志。最近的操作导致一个补码溢出——正溢出或者负溢出。
循环
1.do-while
效果是重复执行body-statement,对test-expr求值,如果为非零,继续循环。
2.while
第一次执行body-statement之前,循环就可能终止。
3.for
程序首先对初始表达式init-expr求值,然后进入循环,循环中它先对测试条件test-expr求值,如果为"假"就会推出,否则执行循环体body-statement,最后对更新表达式update-expr求值
理解指针
第六周内容总结:
程序员可见状态
Y86程序中的每条指令都会读取或者修改处理器状态的某些部分这称为程序员可见状态。这里的"程序员"既可以是用汇编代码写程序的人,也可以是产生机器级代码的编译器。
Y86有8个程序寄存器:%eax、%ecx、%edx、%ebx、%esi、%edi、%esp、%ebp。
有3个一位的调价吗:ZF、SF、OF,它们保存最近的算术或逻辑指令所造成影响的有关信息。
Y86代码的唯一工具是汇编器,程序员必须执行本来通常交给编译器、链接器和运行时系统同来完成的任务。
指令集模拟器称为YIS,模拟Y86机器代码程序的执行,不用试图去模拟任何及具体处理其实现的行为。有助于在有实际硬件可用之前调试程序,也有助于检查模拟硬件或者在硬件上运行程序的结果。
Pushl指令会把栈指针减去4,并且将一个寄存器值写入存储器中,执行pushl%esp时,处理器的行为是不确定的,因为要入栈的寄存器会被同一条指令修改,通常有两种约定:1.压入%esp的原始值,2.压入减去4的%esp值。
组合逻辑电路可以设计成在字级数据上执行许多不同类型的操作。算数/逻辑单元(ALU)是一种很重要的组合电路。
组合电路从本质上讲不存储任何信息。只是简单地相应输入信号,产生等于输入的某个函数的输出。存储设备都是由同一个时钟控制,始终是一个周期性信号,决定什么时候要把新值加载到设备中。两类存储器设备:
·时钟存储器(简称寄存器)存储单个位或字。时钟信号控制寄存器加载输入值。
·随机访问存储器(简称存储器)存储多个字,用地址来选择该读或者该写那个字。
Y86的顺序实现
取值:从存储器读取指令字节,地址为程序计数器PC的值。
译码:译码阶段从寄存器文件读入最多两个操作数。
执行:ALU要么执行指明的操作,计算存储器引用的有效地址,要么增加或减少栈指针。
访存:可以将数据写入存储器或者从存储器读出数据。
写会:最多可以写两个结果到寄存器文件。
更新PC:将PC设置成下一条指令的地址。
小结
ISA在处理器行为和如何实现处理器之间提供了一层抽象。ISA提供了程序执行的一种顺序说明,也就是一条指令执行完了,下一条指令才会开始。
ISA既有RISC指令集的属性,也有CISC指令集的属性。
流水线化通过让不同的阶段并行操作,改进了系统的吞吐量性能。
重要经验:
·管理复杂性是首要问题
·不需要直接实现ISA
·硬件设计人员必须非常谨慎小心
第七周内容总结:
随机访问存储器
分为两类:静态SRAM和动态的DRAM,SRAM比DRAM更快,也贵更多。SRAM用来作为高速缓存存储器既可以用在CPU片上也可以在片下,DRAM用来作为主存以及图形系统的帧缓冲区。
SRAM将每个位存储在一个双稳态的存储器单元里,每个单元使用一个六晶体管电路来实现的,一个属性,可以无限期保持在两个不同的电压配置或状态之一。其他任何状态都是不稳定的——从不稳定状态开始,电路会迅速地转移到两个稳定状态中的一个。
钟摆能在垂直的位置无限保持平衡,但是是亚稳态的。
DRAM将每个位存储为对一个电容的充电。DRAM存储器单元对干扰十分敏感,电容电压被扰乱之后就永远不会恢复了。数码相机和摄像机中的传感器本质上就是DRAM单元的阵列。
存储器系统必须周期性地通过读出,然后重写类刷新存储器的每一位。
DRAM的芯片中的单元被分成d个超单元,每个超单元都由w个DRA单元组成,一个d*w的DRAM总共存储量dw位信息,超单元被组织成一个r行c列的长方形阵列,rc=d,每个超单元有形如(i,j)的地址,i为行,j为列。
DRAM 包装在存储器模块中,它是插在主板的扩展槽上的。常见的包括168引脚的双列直插存储器模块(DIMM),64位为块传送数据到存储控制器和从存储控制器传出数据。72引脚的单列直插存储器模块(SIMM),以32位为块传送数据。
将多个存储器模块连接到存储控制器,能够聚合主存。
·快页模式DRAM
·扩展数据传输出DRAM
·同步DRAM
·双倍数据速率同步DRAM
·Rambus DRAM
·视频RAM
DRAM和SRAM在断电时会 丢失它们的信息,所以它们是易失的。另一方面,非易失性存储器,即使在断电后,也仍然保存着它们的信息。只读存储器ROM,以它们能够被重编程的次数和对它们进行重编程所用的机制来区分的。
PROM(可编程ROM)只能被编程一次,PROM的每个存储器单元有一种熔丝,只能用高电流熔断一次。
EEPROM(可擦写可编程ROM)
闪存是一类非易失性存储器,基于EEPROM,一种重要的存储技术。
存储在ROM设备中的程序通常称为固件。
数据流通过称为总线的共享电子电路在处理器和DRAM主存之间来来回回。每次CPU和主存之间的数据传送都是通过一系列步骤来完成的,这些步骤称为总线事务。读事务从主存传送数据到CPU。写事务从CPU传送数据到主存。
总线是一组并行的导线,能携带地址、数据和控制信号。取决于总线的设计,数据和地址信号可以贡献同一组导线,也可以使用不同的,两个以上的设备也能共享同一根导线。
磁盘存储
1.磁盘构造
磁盘是由盘片构成的。每个盘片有两面或者说是表面,表面覆盖着磁性记录材料。盘片中央有一个可以旋转的主轴,它使得盘片以固定的旋转速率旋转,通常是5400~15000转每分钟。
每个表面是由一组成为磁道的同心圆组成的。每个磁道被划分为一组扇区,每个扇区包含相等数量的数据位,这些数据编码在扇区的磁性材料中。扇区之间由一些间隙分隔开,这些间隙不存储数据位,间隙存储用来标识扇区的格式化位。
2.磁盘容量
一个磁盘上可以记录的最大位数称为它的最大容量,磁盘容量是由以下技术因素决定的:
记录密度(位/英寸):磁道一英寸的段中可以放入的位数。
磁道密度(道/英寸):从盘片中心出发半径一英寸的段内可以有的磁道数
面密度(位/平方英寸):记录密度与磁道密度的乘积
磁盘容量公式:
磁盘容量=× ×××
3.磁盘操作
磁盘用读/写头来读写存储在磁性表面的位,而读写头连接到一个传动臂一端。这样的机械运动成为寻道。
磁盘以扇区大小的块来读写数据,对扇区的访问时间有三个主要的部分:寻道时间、旋转时间、传送时间。
寻道时间:为了读取某个目标扇区的内容,传动臂首先将读写头定位到包含目标扇区的磁道上,移动传动臂所需的时间称为寻道时间。
旋转时间:一旦读写头定位到了期望的磁道,驱动器等待目标扇区的第一位旋转到读写头下。
Tmax rotation =×
平均旋转时间Tavg rotation是Tmax rotation的一半
传送时间:当目标扇区的第一个位位于读写头下时,驱动器就可以开始读或者写该扇区的内容了。
Tavg rotation =××
3.逻辑磁盘块
一个B个扇区大小的逻辑块的序列,编号为0,1……B-1,磁盘中有一个小的硬件/固件设备,称为磁盘控制器,维护着逻辑块号的实际磁盘扇区之间的映射关系。
4.连接到I/O设备
5.访问磁盘
固态硬盘
SSD是一种基于闪存的存储技术。一个SSD包由一个或多个闪存芯片和闪存翻译层组成,闪存芯片替代传统旋转磁盘中的机械驱动器,而闪存翻译层是一个硬件/固件设备,扮演与磁盘控制器相同的角色,将对逻辑块的请求翻译成对底层物理设备的访问。
随机读和写的性能差别是由底层闪存基本属性决定的。
随机写很慢,两个原因:1.擦除块需要相对较长的时间,比访问页所需时间要高一个多数量级。2.如果写操作试图修改一个包含已经有数据的页p,那么这个块中所有带有用数据的页都必需被拷贝到一个新块,然后才能进行对p的写。
SSD优点:随机访问时间比旋转磁盘要快,能耗更低,同时也更结实。
局部性
一个编写良好的计算机程序常常具有良好的局部性,倾向于引用临近与其他最近引用过的数据项的数据项,或者最近引用过的数据项本身。被称为局部性原理。
二种不同形式:时间局部性,空间局部性。
局部性小结
简单原则:
·重复引用同一个变量的程序有良好的事件局部性
·对于具有步长为k的引用模式的程序,步长越小,空间局部性越好。具有步长为1,的引用模式的程序有很好的空间局部性。在存储器中以大步长跳来跳去的程序空间局部性会很差。
·对于取指令来说,循环有好的时间和空间局部性,循环体越小,循环迭代次数越多,局部性越好。
存储器层次结构
属性:
·存储技术:不同存储技术的访问时间差异很大。
·计算机软件:一个编写良好程序倾向于展示出良好的局部性
存储器层次结构,所有现代计算机系统都是用这种方法。
存储器层次机构中的缓存
高速缓存是一个小而快速的存储设备,它作为存储在更大、也更慢的设备中的数据对象的缓冲区域。使用高速缓存的过程称为缓存。
当程序需要k+1层的某个数据对象d时,它首先在当前存储在第k层的一个块中查找d。如果d刚好在k层,那么就是我们所说的缓存命中。
如果第k层中没有缓存数据对象d,那么就是缓存不命中。
覆盖一个现存的块的过程称为替换或驱逐这个块,被驱逐的这个块有时也叫牺牲块,决定该替换哪个块是由缓存的替换策略来控制的。
如果第k层的缓存是空的,那么对任何数据对象的访问都会不命中。一个空的缓存有时称为冷缓存,此类不命中称为强制性不命中,或冷不命中,通常是短暂的事件,不会再反复访问存储器使得存储器暖身之后的稳定状态中出现。
只要发生了不命中,第k层的缓存就必须执行某个放置策略,确定把它从第k+1层中取出的块放在那里。
这种限制性的放置策略会引起一种不命中,称为冲突不命中。这种情况下,缓存足够大能够保存被引用的数据对象,但是因为这些对象会映射到同一个缓存块,缓存会一直不命中。
程序通常是按照一些列阶段来运行的,每个阶段访问缓存块的某个相对稳定不变的集合。称为这个阶段的工作集,当工作集的大小超过缓存的大小,缓存会经历容量不命中,也就是缓存太小了不能处理这个工作集。
存储器层次结构的本质是,每一层存储设备都是较低一层的缓存。
高速缓存存储器
早期计算机系统的存储器层次结构只有三层:CPU寄存器、DRAM主存储器和磁盘存储。
CPU和主存的差距逐渐增大,CPU寄存器文件和主存之间插入了一个小的SRAM高速缓存存储器,L1一级缓存,访问速度几乎和寄存器一样快,2~4个时钟周期。
随着cpu和主存之间的性能差距不断增大,L1高速缓存和主存之间又插入了L2高速缓存,10个时钟周期可以访问到它。
L3高速缓存也存在了,30~40个时钟周期可访问。
高速缓存存储器结构
一个计算机系统,其中每个存储器地址有m位,形成M=2m个不同的地址。
高速缓存参数的性能影响
指标:
·不命中率
·命中率
·命中时间
·不命中处罚
较大的高速缓存可能会提高命中率,使得大存储器运行的更快总是要难一些。
较大的块能利用程序中可能存在的空间局部性,帮助提高命中率,块越大就意味着高速缓存行数越少,这会损害时间局部性比空间局部性更好的程序中的命中率。
E是每个组中高速缓存行数,较高的相联度(较大的E)的优点是降低了高速缓存由于冲突不命中出现抖动的可能性。较高的相联度会造成较高的成本。
相联度的选择最终变成了命中时间的不命中处罚之间的折中。
直写高速缓存比较容易实现,而且能使用独立于高速缓存的写缓冲区,用来更新存储器。写回高速缓存引起的传送比较少,它允许更多的到存储器的带宽用于执行DMA的I/O设备。高速缓存越往下层,越可能使用写回而不是直写。
高速缓存行、组和块有什么区别
·块时一个固定大小的信息包,在高速缓存和主存之间来回传送
·行是高速缓存中存储块以及其他信息的容器
·组是一个或多个行的集合
编写高速缓存友好的代码
基本方法:
小结
基本存储技术包括随机存储器RAM、非易失性存储器ROM和磁盘。RAM有两种基本类型。静态RAM 即SRAM快一些也贵一些,既可以做CPU芯片上的高速缓存也可以做芯片下的高速缓存,动态RAM即DRAM慢一些也便宜一些,做主存和图形帧缓冲区。非易失性存储器即只读存储器ROM即使在断电的时候也能保持它们的信息,用来存储固件。旋转磁盘是机械的非易失性存储设备,以每个位很低的成本保存大量的数据,但是访问时间比DRAM更长,SSD固态硬盘基于非易失性的闪存,越来越变成旋转磁盘对某些应用的具有吸引力的代替产品。
较快的存储技术每个位的价格会更高,而且容量较小。DRAM和磁盘访问时间远远大于CPU周期时间,系统通过将存储器组织成存储设备的层次结构来弥补这些差异,在这个层次结构中,较小、较快的设备在顶部,较大、较慢的设备在底部。
程序员可以通过编写有良好空间和时间局部性的程序来显著改进程序的运行时间,利用基于SRAM的高速缓存存储器特别重要,主要从高速缓存取数据的程序能比主要从存储器取数据的程序运行的快得多。