diff --git a/Computer-Organization/2-storage-system-ex.md b/Computer-Organization/2-storage-system-ex.md index f69bf32..d80b643 100644 --- a/Computer-Organization/2-storage-system-ex.md +++ b/Computer-Organization/2-storage-system-ex.md @@ -389,7 +389,7 @@ $C.12.5\%$ $D.25\%$ -解:$C$。分析语句`a[k]=a[k]+32`,首先读取`a[k]`需要访问一次`a[k]`,之后将结果赋值给`a[k]`需要访问一次,共访问两次。第一次访问`a[k]`未命中,并将该字所在的主存块调入$Cache$对应的块中,对该主存块中的$16\div4=4$个整数的两次访问中,只在访问第一次的第一个元素时发生缺失,其他的$4\times2-=7$次访问中全部命中,因此该程序段执行过程中访问数组$a$的$Cache$缺失率约为$1/8$(即$12.5\%$)。 +解:$C$。分析语句`a[k]=a[k]+32`,首先读取`a[k]`需要访问一次`a[k]`,之后将结果赋值给`a[k]`需要访问一次,共访问两次。第一次访问`a[k]`未命中,并将该字所在的主存块调入$Cache$对应的块中,对该主存块中的$16\div4=4$个整数的两次访问中,只在访问第一次的第一个元素时发生缺失,其他的$4\times2-1=7$次访问中全部命中,因此该程序段执行过程中访问数组$a$的$Cache$缺失率约为$1/8$(即$12.5\%$)。 **例题** 设$Cache$由$8$个块构成,$CPU$依次访问的主存地址块号为:$4$,$6$,$12$,$4$,$8$,$14$,$22$,$6$,$4$,$11$,$5$,$2$(十进制),求: diff --git a/Computer-Organization/2-storage-system.md b/Computer-Organization/2-storage-system.md index 4866e58..388f3f5 100644 --- a/Computer-Organization/2-storage-system.md +++ b/Computer-Organization/2-storage-system.md @@ -403,42 +403,77 @@ M0|M1|M2|M3 地址以字节为单位。 +默认都需要一位有效位。 + 注意:$Cache$字块标记是指$Cache$有多少行,而不是有多少容量,往往以字为单位。 #### 直接映射 +存储方式: + + 对号入座,每一个主存块只能存放在唯一一个地方。 + 将主存储体按$Cache$存储体的长度划分为多个区,主存的每个区只能放在$Cache$的指定区域中。类似于模运算,将主存长度对$Cache$长度取模,地址相同余数的内存块放在同一个$Cache$块中。 -+ 这种映射方式也需要一位有效位标识是否有数据存储,也需要存入主存块号来标识存入的是哪个。 -+ 若发生冲突,不需要替换算法直接替换出去。 -+ 但是与全相连映射不同的是,因为直接映射是根据模运算来存储的,所以行与行之间是顺序的关系,所以主存块号不需要全部存入标记项,把能区分相同模结果的地址前一部分位的数据存入即可。 -+ 如$Cache$一共八行,则主存按八为一个周期存储,则如$Cache$的$0$号地址中一定存入主存块地址模八后余$0$的主存块,即地址都为为$xx\cdots000$,同理$1$号地址存的都是$xx\cdots001$,所以可以保存主存地址减三的前面位数就足够了。这里的$000$和$001$等类似于$Cache$的组号。若$Cache$的行数为$2^n$,主存块号地址为$c$位,则标记项只用保存$c-n$位就可以了。 + +地址组成: + + 地址=主存字块标记+$Cache$字块标记+字块内地址。 + $Cache$地址=$Cache$字块标记+字块内地址。 + 主存字块标记为主存容量除以$Cache$容量,表示要用多少位来区分主存地址。 -+ $Cache$字块标记的位数为$Cache$的块数的二对数。 ++ $Cache$字块标记,即$Cache$行号的位数为$Cache$的块数的二对数。 + 字块内地址就是块内地址,位数为每块容量的二对数。 + +附加位: + ++ 这种映射方式需要一位有效位标识是否有数据存储。 ++ 若发生冲突,不需要替换算法直接替换出去。所以不需要替换位。 ++ 但是与全相连映射不同的是,因为直接映射是根据模运算来存储的,所以行与行之间是顺序的关系,所以主存块号不需要全部存入标记项,把能区分相同模结果的地址前一部分位的数据存入即可。 + +特点: + + 优点:节省掉$Cache$字块标记,有效位存储的地址减少,实现难度降低。 + 缺点:空间利用率降低。 +如$Cache$一共八行,则主存按八为一个周期存储,则如$Cache$的$0$号地址中一定存入主存块地址模八后余$0$的主存块,即地址都为为$xx\cdots000$,同理$1$号地址存的都是$xx\cdots001$,所以可以保存主存地址减三的前面位数就足够了。这里的$000$和$001$等类似于$Cache$的组号。若$Cache$的行数为$2^n$,主存块号地址为$c$位,则标记项只用保存$c-n$位就可以了。 + #### 全相联映射 -+ 空位随意放,因为无法查看$Cache$里面每个存储块是否有数据,所以还需要一个有效位来表示里面是否有数据,将有效位放入标记项中。 -+ 但是这时候还是不知$Cache$里的每一个存储单元存的是主存的哪一块数据,所以还需要将主存的主存块号保存到标记项中,从而标记项数据的第$1$位代表$Cache$该单元是否存储数据即有效位,后面的位标识存储的是主存哪一块数据即主存字块标记。 +存储方式: + ++ 空位随意放。 ++ 但是这时候还是不知$Cache$里的每一个存储单元存的是主存的哪一块数据,所以还需要将主存的主存块号保存到标记项中。 + 因为是乱序存放,所以一定要把整个主存块号都放入标记项中。 + +地址组成: + + 地址=主存字块标记+字块内地址。 + +附加位: + ++ 因为无法查看$Cache$里面每个存储块是否有数据,所以还需要一个有效位来表示里面是否有数据,将有效位放入标记项中。 + +特点: + + 优点:冲突概率低;空间利用率高,命中率高。 -+ 缺点:标记比较速度慢,实现成本高。 ++ 缺点:标记比较速度慢,实现成本高(相联存储器)。 #### 组相联映射 +存储方式: + + 按号分组,组内随意放,结合了上面二者的优点。 -+ 也需要有效位,标记项也需要存入能区分数据块的部分地址。 ++ 标记项也需要存入能区分数据块的部分地址。 + 将$Cache$的块分为几个组,主存不再按照$Cache$的行数进行模运算分组存入,而用$Cache$组的个数进行模运算,虽然这样能节省的位数变少,但是这样主存的某一块就可以在每一组内随机选一个存储,而不用只能存储在一个块内浪费其他块的空间。 -+ 地址=主存字块标记+$Cache$组内地址+字块内地址($Cache$每行长度)。 - -+ 当$Cache$组地址位数长度变为表示$Cache$行数的二进制位,那么组号和行号一样就变成了直接映射,若组地址位数为$0$,则$Cache$不分组都随机存储即变成了全相连映射。 ++ 每组有$r$个行,则称为$r$路组相联。 + +地址组成: + ++ 地址=主存字块标记+$Cache$组号+字块内地址($Cache$每行长度)。 + 一般物理地址的中间部分直接映射为组号。 ++ 当$Cache$组地址位数长度变为表示$Cache$行数的二进制位,那么组号和行号一样就变成了直接映射,若组地址位数为$1$全部为一个组,则$Cache$不分组都随机存储即变成了全相连映射。 + +附加位: + ++ 需要有效位。 ![地址映射][addressreflect] @@ -448,7 +483,9 @@ M0|M1|M2|M3 标记项的长度=标记位长度+其他位长度(如有效位、替换控制位、一致控制位即脏位)。 -有效位和脏位默认都是一位。替换控制位主要用于组相联映射方式。多少路组相联的二对数对应多少位替换控制位。如两路组相联对应标记项的一位替换控制位,物理地址的$Cache$组标记为三位对应八组,则一共有十六行$Cache$行。 ++ 有效位默认是一位。 ++ 替换控制位主要用于组相联映射方式,其他两种方式基本上没有这个。多少路组相联的二对数对应多少位替换控制位。如两路组相联对应标记项的一位替换控制位,物理地址的$Cache$组标记为三位对应八组,则一共有十六行$Cache$行。 ++ 脏位默认是一位。如果是写回法和写分配法则需要,全写法和非写分配法则不需要。 标记位长度=主存地址长度(即主存总容量位数而不是$Cache$容量长度)-其他地址长度(块内地址,即$Cache$行的数量的对数;组地址,即多少个组的对数)。 diff --git a/Operate-System/1-process-management.md b/Operate-System/1-process-management.md index ee51c95..5bffbef 100644 --- a/Operate-System/1-process-management.md +++ b/Operate-System/1-process-management.md @@ -846,6 +846,8 @@ flag[1] = false; // ⑩ 访问完临界区,表示自己已经不想访问临 remainder section; ``` +如果出现两个进程并发的情况,则其中一个进程必然被卡住,另一个进程必然会执行,所以不存在饥饿和死锁问题。 + $Peterson$算法用软件方法解决了进程互斥问题,遵循了空闲让进、忙则等待、有限等待三个原则,但是依然未遵循让权等待的原则。 ### 进程互斥硬件实现 @@ -1610,7 +1612,7 @@ monitor Demo { 条件变量与信号量: + 相似点:条件变量的$wait/signal$操作类似于信号量的$PV$操作,可以实现进程的阻塞/唤醒。 -+ 不同点:条件变量是“没有值”的,仅实现了“排队等待”功能;而信号量是“有值”的,信号量的值反映了剩余资源数,而在管程中,剩余资源数用共享数据结构记录。 ++ 不同点:条件变量是“没有值”的,仅实现了“排队等待”功能(所以一旦调用就不用判断,直接阻塞或释放);而信号量是“有值”的,信号量的值反映了剩余资源数,而在管程中,剩余资源数用共享数据结构记录。 #### 处理同步互斥问题