文章目录
存储器的层次结构
特点:
- 每位价格递减
- 容量递增
- 存取时间递增
- 处理器访问存储器频率递减
概念
局部性原理:在程序执行期间,处理器的指令访存和数据访存呈"簇"(一组数据集合状).
高速缓存
出现原因
处理器与内存速度不匹配,于是基于局部性原理,在处理器和内存间提供一个容量小且速度快的存储器.使得访问速度接近现有的最快存储器,同时支持价格低的大存储容量.
原理
直接内存存取
执行IO操作技术
- 可编程IO
- 中断驱动IO
- 直接内存存取(DMA)
当处理器遇到IO相关指令,它会通过给IO模块发命令来执行这个指令.
使用可编程IO时,IO模块执行请求的动作并设置IO状态寄存器中相应的位,但并不会进一步通知处理器.所以处理器在执行IO指令后,还需要定期检查IO模块状态,以确定IO完成.
中驱动IO:处理器给IO模块发送命令,然后处理器做自己的事,IO模块准备好与处理器交换数据时,它将打断处理器的执行并请求服务.
存在缺点:
IO传送速度受限于处理器测试设备和提供服务的速度
处理器忙于管理IO传送的工作,必须执行很多指令才完成IO传送
解决方法:DMA
DMA由一个独立模块完成,当处理器执行IO操作时,给DMA发送一条命令,然后有DMA去处理IO,处理完后,中断处理.
缺点:DMA需要控制总线来与存储器进行数据传输,所以会影响处理器访问控制总线的速度.
操作系统
结构
进程实现
进程表记录每个进程的表项(进程存储地址指针以及部分或全部执行上下文)
进程索引寄存器,包含当前正在控制处理器的进程在进程表中的索引
程序计数器指向该进程中下一条执行的指令
基址寄存器和界限寄存器分别限制该进程上下边界地址
程序计数器在基址寄存器和界限寄存器地址范围内进行执行.保证进程之间不会相互干涉.
windows
进程
由程序代码,数据集以及进程控制块组成
二状态进程模型
五状态模型
处理器以轮转方式操作可运行的进程(依次给每个进程执行时间,然后进程返回FIFO队列,阻塞情况除外),但是还有一些处于阻塞等待IO操作结束的进程.分派器扫描队列时,需要寻找未被阻塞且在队列中时间最长的进程.
解决办法:非运行态分成就绪和阻塞态.
排队模型
挂起态
存在问题
当进程阻塞过多,处理器大多数时间处于空闲状态.
解决方法
加内存
缺点:价格上升,其次更大内存可能导致更大的进程
写磁盘,当内存中不存在就绪态进程时,
操作系统将阻塞进程写入磁盘
操作系统的控制结构
用户进程结构
线程
用户线程与内核线程
用户线程(ULT):管理线程的所有工作都由应用程序完成,对内核屏蔽.
优点:
线程切换不需要内核模式特权
可自定义线程调度算法
ULT跨操作系统执行,不需要根据底层内核修改
缺点:ULT执行系统调用时,阻塞整个进程
多线程不能利用多处理技术,内核一次只把一个进程分配给一个处理器.因此一个进程只能一个线程执行
解决办法:多进程程序,但每次切换变成进程级,开销过大
套管,将一个阻塞系统调用转成非阻塞.
内核线程:管理线程由内核完成,内核负责维护线程上下文信息.
优点:可将同一个进程的多个线程调度到多处理器上
进程中某线程阻塞,内核可调度同一个进程另一个线程.
内核例程自身也多线程
缺点:线程控制权转让时,需要切换内核模式.
混合模式:同一个应用程序的多个线程映射到多个内核级线程上,可在多个处理器上并行运行.
线程调度和同步,在应用程序完成
Linux线程/进程模型
并发性
进程的交互
互斥
硬件的支持
单处理机器中,通过中断禁用实现.
缺点:处理器限制只能交替执行程序
不适用多核
机器指令
echange
compare_and_swap
优点:支持多核
缺点:当一个线程等待进入临界区,会继续消耗CPU时间
可能饥饿
可能因为线程优先级造成死锁
T1进入临界区,中断.优先级高的T2执行,若T2和T1使用同一资源,因为优先级高于T1,则T1永远不会执行.造成死锁
信号量
count>=0,count=可执行wait而不被阻塞的进程数
count<0, |count|是阻塞在queue中的进程数
信号量,使用队列保存等待的进程,出队策略FIFO称之为强信号量,不按照规则的则是弱信号量.也就是抢占式和公平策略.
无界生产者消费者
有界生产者消费者
信号量的实现
管程
操作系统或程序设计语言支持
内存
内存分区
固定分区
使用大小相等分区存在问题
- 程序太大不能放入分区,必须使用覆盖技术设计程序
- 程序太小,造成内存利用率低,存在空间浪费.也就是存在内部碎片
- 分区数量在系统生成阶段已确定,因此限制了系统中活动进程数量
使用大小不等,并不能完全解决问题.
二种分配策略
每个进程分配到能容纳它的最小分区中,每个分区维护一个调度队列,保存从这个分区换出的进程
为所有进程提供一个队列,每个进程分配到能容纳它的最小分区中,当所有分区满了,则进行交换出内存.
动态分区
缺点:随着时间推移,内存中存在越来越多的空洞.
解决办法:压缩.操作系统不时移动进程,使进程占用空间连续,并使所有空闲空间连成一片.
放置算法
最佳适配:选择与要求大小最接近的块
因为需要全局扫描选择最优,所以性能差,
而且也会产生很小碎片,造成无法分配,
需要频繁内存压缩
首次适配:从头扫描内存,选择大小足够的第一个可用块
简单,速度快,前端出现碎片
下次适配:从上一次放置地方开始扫描内存,选择下一个大小足够块
通常内存末端分配空间,导致末端存在碎片
伙伴系统
若2个伙伴均为叶子节点,则至少分配出去一个,否则合并.
分页
将内存和进程分成同样大小的小块,进程中称为页的块可以分配到内存中称为页框的可用块.
则每个进程在内存中浪费的空间,仅仅是进程最后一页的一小部分形成的碎片.
注意:当没有连续的页框保存进程D时,操作系统通过为每个进程维护一个页表,页表记录该进程每页所对应页框的位置.
如何寻址的?当给出逻辑地址(页号,偏移量)后,处理器使用页表产生物理地址寻址.(页框号,偏移量)
与固定分区对比,分页的分区非常小,一个程序可占据多个分区,且分区不需要是连续的.
分页的好处,假设一个逻辑地址由页号n+偏移量m组成.
则寻址只需要根据n查找进程表中对应的页框号k即可
根据页框号k得出物理地址k*2^m,加上偏移量m就能得出具体物理地址.
分段
类似动态分区,但段不要求连续,可必须要知道段最大长度限制.编写的程序可以指定所在段.
虚拟内存
将进程部分块挂载到磁盘中,当执行进程获取不到块时,中断加载
分页
基于虚拟内存的分页与简单分页的不同是增加了P位,来表示它所对应的页当前是否在内存中.若在,则这个页表项还包括该页页框号.
另外新增一个修改位M,表示相应页从上次装入内存到现在是否修改.
若未修改,无须用页框中内容更新该页.
页表结构
每个进程拥有一个页表,当页表项过于大的时候,就需要采用二级方案组织大型页表.
也就是多了一个页目录X,每项指向一个页表Y,每个进程可以有XY页,一个页表容量为一页.
倒排页表结构
转换检测缓冲区
每次虚存访问会引起2次物理内存访问,一次取相应页表项,另一次取需要数据,引申出转换检测缓冲区(TLB)进行缓存页表项
当虚地址转为实地址时,需要访问页表项,而页表项可能在TLB中,也可能内存或者磁盘中.被访问的字可能在高速缓存中,内存中或磁盘中.若被访问的字在磁盘中,则包含该字的页装入内存,所在的块装入高速缓存,包含该字的页表项必须更新.
分段
段页式
虚拟内存操作系统策略
读取策略
请求分页:访问某页时在去加载
预先分页:提前加载页
放置策略
如何决定一个进程块驻留在实存那个位置
参考本文最佳匹配,首次匹配.
置换策略
当内存中所有页框都被占据,且需要读取一个新页以处理一次缺页中断时,置换策略决定置换当前内存中那一页.
目标:移出最近最不可能访问的页面.根据局部性原理,最近的访问历史和最近要访问的模式间有很大的关联性.
注意:
- 置换一个修改后的页,因为还不需要写入辅存,所以代价比置换尚未修改的页要大.
- 某些页框可能被锁定,导致无法被置换.
4种置换算法
OPT:置换下次访问距当前时间最长的那些页.
Clock
Clock2,利用修改位
页缓冲
简单的FIFO,将需要置换的页依然留在内存中,但是移动页表项到空闲页或修改页链表中.页在内存中不移动,移动的只是该页对应页表项,移动后的页表项放置空闲页或修改页链表
优点:已修改的页按簇写入磁盘,而不是一页一页写入.
驻留集管理
给进程分配页过少,则驻留内存进程就更多,也就更能增加发现就绪进程可能,减小了由于交换而消耗的处理器时间.
若进程在内存中页过少,尽管有局部性原理,但缺页率依然很高.
若进程在内存中页过多,由于局部性原理,缺页率没明显变化.
也就是说设计的要求就是,内存中尽量驻留过多进程,但是每个进程的页读取数量也保持在一个缺页率低的范围内.
基于目标,有2种设计策略
- 固定分配策略
- 可变分配策略,在一个进程生命周期中不断发生变化,若缺页率高,则分配多页框.否则减少页框.
置换范围
- 局部:在缺页进程中移出的一页必须由同一进程另一页置换.固定分配策略使用
- 全局:一个进程的某一页置换另一进程的某一页.可变分配策略使用