缓存中使用虚拟寻址的设计问题

本文探讨了虚拟寻址缓存在操作系统设计中的复杂性,特别是在多进程环境下,相同虚拟地址可能导致的数据读取错误。文章详细介绍了操作系统如何管理缓存以防止此类错误,包括在权限注销后清除缓存数据,以及在写回缓存中如何处理权限验证。

摘要自:Unix Systems for Modern Architectures – Symmetric Multiprocessing and Caching for Kernel Programmers by Curt Schimmel: Chapter 3 “Virtual Caches”

虚拟寻址缓存根据指令或者数据的虚拟地址作为索引 (index) 和标记 (tag)。这在一定程度上让操作系统的设计变得复杂,因为不同进程可以有相同的虚拟地址。如果设计出错,一个进程缓存的数据可以被另一个进程读取,导致错误。为阻止这种情况发生,操作系统必须在此之前将缓存清空。本章介绍虚拟寻址缓存的各种操作,歧义、重名是如何发生的,以及操作系统如何才能组织这类错误对程序正确运行的影响。本章只考虑单核CPU的情况。

使用虚拟寻址缓存的系统中,如果缓存命中(cache hit),对数据的读操作可以通过MMU,也可以不同过MMU。比如,Intel i860 系列,在取指令阶段,如果缓存命中,MMU不会翻译虚拟地址。这意味着硬件不会对这次读操作执行权限的验证。这种情况也存在于Apollo DN4000 以及 Sun 3/200 中。在这类系统中,MMU 仅仅对缓存未命中的虚拟地址执行翻译以及权限验证操作。这里隐含着一个默认的假设,即如果一个程序在缓存未命中时有权限访问某一数据,那么他在后续的运行中如果发生缓存命中,它仍然有权限访问这个数据。操作系统必须保证在程序权限注销后,缓存的数据也标记失效(invalidated).

在写回类型的缓存中,验证一个请求的访问权限较(直写类型)复杂一点。假设缓存支持写分配(write-allocate),因为这是写回缓存的通常做法,那么一个未命中的写请求会调用MMU去翻译地址并检查权限。权限通过则载入缓存,并设置修改位为1。如果缓存架构中没有写分配,则一个未命中的写请求的处理过程同直写类型的缓存一样:数据只被写入内存中,缓存内容保持不变。

如果在写回缓存中,写请求的地址在缓存中命中,而且该地址在缓存中被标记为已修改,则我们可以默认其修改权限为合法的。因为我们可以比较安全的假设之前修改此地址内容时该进程已经有了写权限。

但是,如果写请求的地址在缓存中命中,而且该地址并没有被标记为已修改,则我们就无法从缓存中推断该进程对该地址到底有没有写权限。这时,就需要调用MMU来进行权限检查。这是Intel i860 XR的缓存设计所采取的方法。

而在Apollo DN4000 的写回缓存中,增加了一个可写权限位,从而避免了在更新缓存过程中要调用MMU验证权限的过程。缓存中的可写权限位是在内存页表中写权限位的一个副本。

### 虚拟存储器中的指令寻址方式与原理 虚拟存储器通过引入地址映射机制来支持大容量逻辑地址空间的访问,从而使得程序可以像拥有无限内存一样运行。以下是关于虚拟存储器中指令寻址的方式及其工作原理的具体说明。 #### 地址映射机制 在虚拟存储器中,地址分为 **虚地址(虚拟地址)** 和 **实地址(物理地址)**。当处理器发出一条指令时,会生成一个虚地址用于访问数据或代码。这个虚地址需要经过特定的转换过程才能找到对应的物理地址并完成实际的数据读写操作[^1]。 - **静态重定位**: 这种方法是在编译或者链接阶段就完成了从逻辑地址到物理地址的变换, 不适用于现代动态加载环境下的虚拟存储体系结构. - **动态重定位 (重点)**: 动态重定位发生在运行期间,在每次访存的时候都会实时计算出最终使用的物理地址位置。这种方式依赖硬件的支持以及专门设计的操作系统软件配合实现复杂的功能需求如页面替换算法等. 具体来说,动态重定位主要涉及以下几个组件: 1. **页表(Page Table)** – 记录每一个虚拟页对应的实际框架号(Frame Number),形成一对一的关系; 2. **快表(TLB - Translation Lookaside Buffer)**– 缓存最近频繁使用的几项条目以加速查找效率减少延迟时间消耗; 3. **缺页中断处理程序(Missing Page Handler)** 当发现当前试图访问的目标不在RAM当中而是位于磁盘文件里头的话就会触发该事件进而采取措施将其载入可用空闲区供后续继续正常流程运转下去直到整个任务结束为止[^1]. #### 寻址过程详解 假设存在这样一个场景:CPU执行了一条LOAD命令准备获取某个变量X的内容。此时如果采用的是请求分页式的虚拟存储方案,则大致遵循以下步骤完成此次取数动作: 1. CPU依据源码产生的相对偏移量构建起完整的虚拟地址VA(Value Address); 2. 查询TLB看是否存在匹配记录加快响应速度;如果没有命中则转至下一步骤; 3. 查阅主存里的全局/进程专属页表寻找关联关系得到PFN(Page Frame Number), 并据此组装成PA(Physical Address)=PFN*PageSize+Offset ; 4. 如果上述第三步失败表明发生了Page Fault现象于是启动相应的异常处置子例程负责解决此状况比如安排新近未用过的帧腾出来接纳即将调回的新资料片段等等最后再重复前面提到的过程直至成功返回所需数值给最初发起者使用即可. ```python def virtual_to_physical(virtual_address, page_table, tlb): offset = virtual_address % PAGE_SIZE # Check TLB first for faster access if virtual_address in tlb: frame_number = tlb[virtual_address] else: # If not found in TLB, consult the main memory's page table page_number = virtual_address // PAGE_SIZE try: frame_number = page_table[page_number] # Update TLB with this new mapping to speed up future accesses tlb[virtual_address] = frame_number except KeyError as e: raise PageFaultException(f"Virtual address {virtual_address} is not mapped.") physical_address = frame_number * PAGE_SIZE + offset return physical_address ``` 以上伪代码展示了如何将虚拟地址转化为物理地址的一个简化版本模型。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值