Lecture 32: VM I: Intro
The Computer
New-school Machine Structures
软件和硬件结构的并行性
现代计算机系统通过并行性显著提升性能,这种并行性体现在软件和硬件的多个层面。
-
软件层面的并行性:多个请求可以同时被计算机处理。比如在搜索引擎中,用户可以同时搜索多个关键词,系统会为每个请求分配不同的线程来处理。每个线程可以被分配到不同的核心,从而实现并行处理。具体而言,当你在浏览网页时,浏览器后台可能会同时加载多个资源,如图片、脚本和样式表,这些任务由不同的线程在多个核心上并行执行。
-
硬件层面的并行性:计算机内部的多个组件能够同时工作。例如,CPU中的执行单元和其他功能模块可以同时处理多个数据项。具体来说,现代处理器通常包含多个核心,每个核心又包括多条流水线,这些流水线可以在同一时刻处理不同的指令。此外,硬件加速器(如GPU、TPU)能够在大规模数据并行处理中发挥重要作用,广泛应用于图像处理、机器学习等领域。这种并行架构不仅存在于高性能计算机中,也在智能手机等小型设备中得到应用,如同时运行多个应用程序或后台任务。
CS61C so far…
课程进展概述
到目前为止,CS61C课程覆盖了从C语言编程到RISC-V汇编和CPU设计的内容。
-
编程到汇编:学生通过课程学习如何将高级语言(如C语言)编写的程序转换为RISC-V汇编指令。这一过程帮助学生理解高级语言代码如何被编译器逐步分解为计算机能够直接执行的低级指令。
-
CPU执行流程:在学习汇编指令之后,课程进一步探讨了这些指令在CPU内部的执行过程,包括指令的取指、译码、执行、访存和回写等步骤。学生通过项目逐步掌握了CPU内部结构的运行机制,如如何通过流水线技术加速指令执行,以及如何处理缓存与内存之间的数据交互。
-
硬件实现:课程还介绍了如何在硬件层面实现这些指令的执行,包括设计简单的CPU模型,理解控制单元和数据路径的作用,进一步加深对计算机工作原理的理解。
But Wait…
实际设备与学习模型的差异
在使用Venus模拟器进行实验时,我们通常只能执行一个程序,执行结束后模拟器停止运行。然而,现实中的计算机系统却要复杂得多。
-
多任务处理:当你打开笔记本电脑时,操作系统(如Windows、Linux)能够同时管理和运行多个程序。这是通过多任务处理实现的,即操作系统会为每个运行的程序分配足够的资源(如内存、CPU时间),并通过时间片轮转等机制让多个程序看似同时运行。
-
输入输出设备的协同工作:同时,计算机中的多个输入输出设备(如屏幕、键盘、存储设备等)也在协同工作。例如,当你在键盘上输入文字时,操作系统会立即响应并将文字显示在屏幕上,而在后台,存储设备可能正在进行数据读取或写入操作。
-
虚拟内存的作用:操作系统还利用虚拟内存技术来管理和隔离不同程序的内存空间。虚拟内存不仅扩展了物理内存,还允许每个程序运行在自己的独立内存空间中,防止相互干扰。理解虚拟内存和操作系统如何管理并行任务,对于深入掌握现代计算机系统的复杂性至关重要。
Raspberry Pi ($35) and I/O Ports
Raspberry Pi简介:
Raspberry Pi是一种低成本的计算机,其主板集成了CPU、输入输出(I/O)接口、缓存等组件,形成一个完整的小型计算设备。图中的“$”符号代表缓存,表示Raspberry Pi中缓存的重要性。作为一台功能全面的小型计算机,Raspberry Pi足够支持CS61C课程中的实验需求,学生可以通过该设备亲身实践计算机体系结构的原理与应用。
Raspberry Pi的I/O端口:
Raspberry Pi配备了多种I/O接口,使其能够与外部设备进行广泛的交互。例如:
- 存储接口:Micro SD卡槽用于存储操作系统和数据。
- 显示接口:HDMI接口可连接显示器,输出高分辨率图像。
- 网络接口:配备WiFi和以太网接口,支持有线和无线网络连接。
- 通信接口:多个USB接口支持连接键盘、鼠标、外部存储设备等。串行通信接口(如GPIO)还允许Raspberry Pi与其他电子设备进行低级别的通信和控制。
这些丰富的I/O端口不仅让Raspberry Pi能运行多种应用,还支持学生通过连接和控制不同外部设备来实现更复杂的计算和控制任务,扩展其实用性和学习体验。
The Next Step of CS61C
CS61C课程的下一步:
在CS61C课程中,学生已经从编写C语言程序开始,逐步学习如何将这些程序转换为RISC-V汇编代码,并理解CPU内部如何执行这些指令。这一系列项目使学生能够掌握从高级语言到硬件执行的完整流程。接下来,课程将深入探讨计算机系统的其他关键组件,特别是存储器(如DRAM)、存储设备(如磁盘)与输入输出设备(I/O)之间的交互。
通过使用Raspberry Pi,学生可以在实际硬件上操作这些设备,亲自体验从数据存储到设备控制的各种概念。这不仅有助于巩固理论知识,还能让学生在实践中理解计算机体系结构的复杂性和重要性,从而更好地准备后续的高级课程和研究。
OS Basics: Context Switching
The OS is “Just Software”
操作系统(OS)是最大的“软件”:
操作系统是计算机中最复杂和最大的软件之一,通常包含数百万行代码。图中展示了不同软件项目的代码行数估计,突显了操作系统(如Windows和Linux内核)的巨大复杂性。这些代码负责管理计算机的硬件资源,并为用户提供与计算机交互的接口。操作系统不仅仅是一个管理工具,它也是确保所有硬件组件高效协作、所有软件程序稳定运行的关键。
Linux内核随时间的变化:
在CS61C课程中,我们主要关注操作系统的内核部分,而不涉及用户界面等其他高层组件。图中展示了Linux内核代码行数随着版本更新的逐步增加,这反映了操作系统内核功能的不断扩展和复杂性增加。随着时间的推移,Linux内核添加了更多的驱动程序、文件系统和网络协议支持,使其能够适应越来越多样化的硬件设备和使用场景。
What Does the Core of the OS Do?
操作系统核心的职责
操作系统是计算机启动时第一个运行的程序,它的核心职责包括启动各种服务和管理硬件设备。这些服务通常包括文件系统管理、网络栈配置等,数量通常超过100个。操作系统还提供与外部设备和用户交互的能力,这些交互主要通过设备驱动程序来实现。设备驱动程序是与硬件直接相关的代码,负责控制和管理机器中的各种硬件设备,使得它们能够被软件程序有效利用。
程序的加载、运行和管理
操作系统通过隔离机制确保每个程序在其独立的“虚拟世界”中运行,这种隔离防止了程序之间的直接干扰,确保系统的稳定性和安全性。为了使多个程序能够共享相同的硬件资源,操作系统还实现了资源共享机制。例如,多个程序可能需要同时访问内存或I/O设备,这些共享通过精密的调度和管理技术来实现。
操作系统利用时间共享技术在多个进程之间快速切换CPU的使用权,使得每个进程都能够得到执行机会。尽管处理器在多个进程之间不断切换,但这种切换速度非常快,以至于人类感觉不到延迟,仿佛多个进程在同时运行。这一机制是现代多任务操作系统能够有效运行的基础。
Multiprogramming at a High Level
多道程序设计(Multiprogramming)简介
多道程序设计是一种操作系统技术,允许多个应用程序(或进程)在同一个CPU上“同时”运行。虽然这些进程共享同一个CPU,但通过操作系统的上下文切换,使得它们看起来像是同时运行的。
上下文切换是指操作系统在非常短的时间内在不同进程之间切换执行。这个过程包括保存当前进程的状态(如程序计数器、寄存器等),并加载下一个进程的状态,以便CPU能够继续执行下一个进程的指令。由于这种切换速度极快,人类几乎无法察觉到任何延迟。
需要注意的是,在上下文切换过程中,操作系统通常不会将数据在主存和磁盘之间频繁交换,因为这样做的开销非常高。相反,操作系统会尽量利用内存中的现有数据,确保上下文切换的效率。
Storage Latency Analogy: How Far Away Is the Data?
存储延迟类比:数据距离有多远?(回顾)
存储延迟是指在不同存储层次中访问数据所需的时间。为了帮助理解这种延迟的差异,可以通过类比来形象化不同存储层次的延迟。例如,寄存器的访问延迟非常短暂,类似于“在头脑中”,这意味着寄存器的访问速度极快,仅需几纳秒。
相比之下,访问主存(RAM)的延迟要更长一些,如同在校园范围内移动一样,通常需要几十到几百纳秒。而磁盘的访问延迟则是最慢的,可能需要几百万纳秒,这种延迟就像从地球飞往太阳系边缘的冥王星。
这种类比突出了为什么计算机设计中要尽量减少慢速存储器的访问,特别是在设计高性能计算机系统时。这也是为什么缓存(如L1、L2缓存)在现代计算机中如此重要的原因,它们可以显著减少访问慢速存储器的次数,从而提高系统的整体性能。
Physical Memory and Disk Storage
Main Memory and Secondary Memory
在计算机系统中,主存储器(Main Memory)和次级存储器(Secondary Memory)扮演着不同的角色,各自具有不同的性能和功能。
主存储器(Main Memory)
主存储器通常指系统内存,即动态随机存取存储器(DRAM)。它的特点是访问速度快,但容量相对较小,且成本较高。DRAM是计算机运行程序时主要使用的存储空间,用于存储正在执行的程序代码和数据。
- 位置与性能:在存储层次结构的金字塔中,主存储器位于中部。它平衡了速度和容量,提供适中的访问速度,能够快速响应处理器的请求,确保程序的高效执行。
- 使用场景:主存储器主要用于存储需要快速访问的数据,如操作系统核心、正在运行的应用程序和临时数据。它的容量决定了系统能同时运行多少程序,以及能够处理的工作负载大小。
次级存储器(Secondary Memory)
次级存储器包括硬盘驱动器(HDD)和固态硬盘(SSD)。次级存储器具有较大的容量和较低的成本,但其访问速度远慢于主存储器。它们主要用于存储大量的数据,如用户文件、媒体、操作系统和应用程序的静态数据等。
- 位置与性能:在金字塔结构中,次级存储器位于底部。尽管其容量巨大,能够存储数TB的数据,但访问速度较慢,使其不适合频繁的读写操作。
- 使用场景:次级存储器适用于存储不常访问的数据,以及在系统关闭时需要持久保存的内容。它们的非易失性特性确保即使在断电后,数据也能保持完整。
Main Memory is DRAM
主存储器主要由动态随机存取存储器(DRAM)构成。DRAM在计算机系统中发挥着至关重要的作用,其工作原理和性能特点如下:
-
访问延迟:DRAM的访问时间较短,访问第一个字通常需要约10纳秒(相当于30-40个处理器周期),后续的字访问延迟为0.5至1纳秒。这种延迟能够支持高速数据传输,使DRAM非常适合用作主存储器。
-
数据的暂时性:由于DRAM使用电容器来存储数据,这些电容器需要定期刷新以保持电荷,否则数据将丢失。这意味着DRAM是易失性存储器(volatile memory),数据在断电后不会保留。
-
与SRAM的对比:静态随机存取存储器(SRAM)通常用于CPU缓存。与DRAM相比,SRAM不需要刷新电荷,数据可以长期保持稳定,这使得SRAM的访问速度更快,约为0.5纳秒。然而,SRAM的成本更高,存储密度较低,因此主要用于需要极高速度的缓存区域,而不是大容量的主存储器。
Storage / “Disk” / Secondary Memory
存储(Storage),或称为次级存储器(Secondary Memory),主要包括固态硬盘(SSD)和机械硬盘(HDD),它们是计算机系统中常用的非易失性存储设备。
固态硬盘(SSD)
- 访问时间:SSD的访问时间为40-100微秒,相当于10万处理器周期左右。与HDD相比,SSD的速度显著更快。
- 成本:每GB的价格在0.05美元到0.5美元之间,虽然较HDD贵,但SSD的速度和可靠性使其成为越来越多系统的首选。
- 技术特点:SSD采用闪存技术,没有机械部件,数据的访问速度更快,且所有存储位置的访问速度一致。这使得SSD不仅在读取速度上占优,还具备更高的耐用性和低功耗。
机械硬盘(HDD)
- 访问时间:HDD的访问时间为5-10毫秒,相当于1000万到2000万处理器周期。由于机械部件的限制,HDD的速度较慢。
- 成本:每GB的价格在0.01美元到0.1美元之间,是一种更为经济的大容量存储解决方案。
- 技术特点:HDD使用机械转动盘片来读写数据,尽管成本低且容量大,但访问速度较慢,特别是在处理大量随机读写操作时表现不佳。然而,对于需要存储大量不常访问的数据,如备份和归档,HDD仍然是合适的选择。
这些次级存储器的技术差异决定了它们在不同使用场景中的适用性。理解这些特性有助于在系统设计和优化中做出更明智的选择。
Aside … How do HDDs Work?
机械硬盘(HDD)的工作原理:
- 内部结构:HDD内部包含一个或多个高速旋转的盘片,这些盘片的转速通常为每分钟7200到10000转。盘片由磁性材料覆盖,能够存储数据。
- 数据读取与写入:数据通过磁头来读写,这些磁头在盘片表面上方悬浮,并在盘片旋转时迅速移动到需要的位置。
- 旋转时间:盘片每旋转一圈大约需要6毫秒,这决定了数据读写的基础时间。
- 随机访问时间:由于磁头需要在盘片上移动并定位到特定数据所在的轨道,随机访问时间大约为3毫秒。这种时间约等于1000万处理器周期,导致HDD的访问速度相比于固态存储器较慢。
HDD的设计使得它非常适合存储大量数据,尤其是对顺序访问要求较高的场景,例如大文件的存储。然而,由于其机械部件的限制,HDD在处理大量随机读写操作时表现不佳,且其旋转部件也意味着更高的功耗和更大的物理磨损,可能导致较高的故障率。
Aside 2 … What About SSDs?
固态硬盘(SSD)的工作原理:
- 技术基础:SSD采用闪存技术,由大量的晶体管构成,无机械旋转部件。这使得SSD在操作中更为安静,耐用性更高。
- 工作方式:SSD可以被看作一个巨大的寄存器文件,能够快速读取和写入数据。由于其非易失性,即使在断电时数据也能保持不丢失。这使得SSD在数据保护和系统恢复上有明显的优势。
- 访问特点:SSD没有机械部件,因此能够快速随机访问任意存储位置。然而,尽管SSD访问速度比HDD快,但与寄存器和DRAM相比仍然较慢。数据的读取和写入以块为单位进行,而非按字节。这意味着在更新少量数据时,可能需要重写整个块,这会影响效率。
- 潜在问题:SSD在长期使用中可能会面临可靠性问题,例如闪存的磨损问题。此外,SSD的某些操作要求较为特殊,如数据不能单独擦除位元,只能擦除整个块,导致写入操作的复杂性增加。
尽管SSD比HDD在速度和可靠性上有明显优势,但其价格相对较高。随着技术的发展,SSD正在逐渐取代HDD成为主流的存储解决方案,尤其是在需要高性能和快速响应的应用场景中。然而,针对大容量的存储需求,HDD仍然是一个经济的选择。
Virtual Memory and Virtual Addresses
The Case for Virtual Memory (1/2)
虚拟内存的一个主要动机是解决主存(RAM)容量小于程序地址空间的问题。
-
地址空间与物理内存的差距:在现代计算机架构中,虚拟地址空间往往大于实际的物理内存。例如,RV32I架构提供了一个32位的地址空间,可以寻址最大4GiB的内存。然而,实际的物理内存(RAM)可能只有1GiB,这就会产生一个问题:程序可能试图访问超出物理内存范围的地址(如0x0FFFF FFFF),导致系统崩溃。
-
虚拟内存的解决方案:虚拟内存通过将程序的大地址空间映射到有限的物理内存上,使得程序可以在超过实际物理内存的虚拟空间中运行。操作系统动态地将这些虚拟地址映射到实际的物理内存中,并通过内存分页和页表管理,确保程序可以无缝地访问需要的数据,即使这些数据暂时不在物理内存中。
虚拟内存的引入不仅解决了内存容量不足的问题,还提供了内存保护和进程隔离的机制。通过虚拟内存,系统能够有效管理多个进程的内存使用,防止进程之间的相互干扰,提高了系统的安全性和稳定性。
The Case for Virtual Memory (2/2)
另一个推动虚拟内存发展的原因是解决多个程序访问同一内存地址的问题。
- 多程序共享内存的挑战:在没有虚拟内存的系统中,如果程序1和程序2尝试访问相同的内存地址(如0x400),但它们的内存需求各不相同,这将导致数据覆盖。例如,程序1可能会覆盖程序2的数据,或者反之,最终导致数据损坏或程序崩溃。
- 虚拟内存的解决方案:虚拟内存为每个进程提供了一个独立的地址空间。尽管程序1和程序2可能在它们的虚拟地址空间中访问相同的地址,操作系统会将这些地址映射到不同的物理内存位置,从而避免数据冲突和覆盖。这种方式确保了程序之间的内存隔离,防止了相互干扰。
通过虚拟内存,操作系统不仅扩展了系统的内存容量,还引入了进程隔离机制,使得每个进程在独立的虚拟空间中运行。这种机制对于多任务操作系统至关重要,因为它保证了系统的稳定性,防止单个进程的故障影响到整个系统或其他进程。
虚拟地址空间的幻象 (Virtual Address Space Illusion)
在计算机系统中,每个进程都运行在它自己的虚拟地址空间中。这种虚拟地址空间为每个进程提供了一个独立的、完整的内存视图,即使多个进程使用相同的虚拟地址,它们彼此之间也不会冲突。这种虚拟地址空间的概念为操作系统的内存管理提供了极大的灵活性。
- 虚拟地址的使用:
- 每个进程使用虚拟地址来访问内存。图中显示了多个进程同时运行的情况,每个进程都有自己的虚拟地址空间。即使所有进程的虚拟地址范围相同,例如从
0x00000000
到0xFFFFFFFF
,它们访问的实际物理内存却是不同的。这种机制确保了进程之间的隔离,使得一个进程的内存操作不会影响到其他进程。
- 每个进程使用虚拟地址来访问内存。图中显示了多个进程同时运行的情况,每个进程都有自己的虚拟地址空间。即使所有进程的虚拟地址范围相同,例如从
- 虚拟地址空间的布局:
- 虚拟地址空间通常被划分为不同的段,例如堆栈段、未用内存、堆段、静态数据段和代码段。每个段负责存储不同类型的数据。通过这种划分,操作系统可以更加高效地管理内存,并确保数据的安全性和一致性。
操作系统中的概念内存管理器 (Conceptual Memory Manager in OS)
在操作系统中,虚拟地址需要通过内存管理器转换为物理地址。这个过程由操作系统的内存管理器负责,它充当了虚拟地址和物理地址之间的翻译器。
- 翻译器/内存管理器的作用:
- 内存管理器接收来自不同进程的虚拟地址请求,并将这些请求转换为实际的物理地址。通过这种翻译机制,操作系统能够在共享的物理内存中为每个进程分配独立的内存区域,确保各个进程之间的内存隔离。
- 物理地址的使用:
- 实际上,内存硬件只使用物理地址。内存管理器将各个进程的虚拟地址映射到物理内存的特定区域中。图中右侧展示了物理内存的结构,不同颜色表示不同进程在物理内存中的分布。尽管进程使用相同的虚拟地址范围,它们的物理地址是完全独立的。
- 内存隔离的重要性:
- 这种虚拟到物理地址的映射不仅提高了系统的安全性,还确保了系统的稳定性。每个进程的内存操作都被限制在其分配的物理内存区域内,从而避免了进程间的相互干扰。
这些图示解释了虚拟内存如何通过地址转换机制来实现进程间的内存隔离,并确保系统的安全和稳定。虚拟地址空间的幻象使得每个进程看似拥有独立的内存,而实际上这些内存操作都被翻译和映射到物理内存的不同区域中。
假设不存在缓存 (Assume Caches Don’t Exist For Now)
在理解虚拟内存时,为了简化概念,我们暂时假设缓存不存在。缓存是用于加速数据访问的快速存储器,但它的存在增加了系统复杂性的理解难度。因此,在初步学习虚拟内存时,忽略缓存有助于我们更清晰地理解虚拟内存的工作原理。
存储层次结构金字塔
图中的金字塔展示了计算机系统中不同存储层次的速度、容量和成本之间的关系:
- 处理器核心和寄存器:位于金字塔的顶端,具有极高的访问速度(纳秒级),但容量极小且成本高昂。
- CPU缓存:分为L1、L2、L3缓存,尽管缓存能显著提高访问速度,但由于我们当前假设不存在缓存,因此忽略它们的影响。
- 主存储器(DRAM):位于中部,速度快、容量中等、价格适中,是程序运行时主要依赖的存储空间。
- 虚拟内存:通过将较慢的次级存储(如SSD、HDD)与较快的DRAM结合,扩展了系统的有效内存容量。
- 次级存储(SSD和HDD):位于金字塔的底部,存储容量巨大但访问速度较慢,适用于存储大量不常访问的数据。
Paged Memory
分页内存 (Paged Memory)
在讨论虚拟内存时,“分页内存”是一个关键概念。分页内存的核心思想是将物理内存和虚拟内存分割成相等大小的块,称为“页”。操作系统通过页表将虚拟地址映射到物理地址,允许每个进程运行在其独立的虚拟地址空间中。
分页内存的工作机制
- 虚拟地址到物理地址的映射:每个进程的虚拟地址空间通过页表映射到物理内存中的实际位置。页表记录了这些映射关系,确保虚拟地址能够正确转换为物理地址。
- 内存管理:操作系统动态管理内存页面,当物理内存不足时,可以将不常使用的页面交换到磁盘上,这种技术称为“页面交换”。
- 内存隔离:分页内存还为不同进程提供了内存隔离,确保进程之间互不干扰,提高系统的稳定性和安全性。
操作系统的虚拟内存管理职责 (OS Virtual Memory Management Responsibilities)
操作系统在管理虚拟内存时,承担着几个重要职责:
-
虚拟地址到物理地址的映射:操作系统负责将进程的虚拟地址映射到实际的物理地址。这一过程依赖于页表等数据结构的维护和管理。
-
利用内存和磁盘:操作系统通过在磁盘上存储部分数据,提供了一个比实际物理内存更大的“虚拟”内存空间。磁盘通常比DRAM大得多,但速度也慢得多,因此操作系统需要平衡这两者的使用,以提供足够大的内存空间而不显著影响性能。
-
保护机制:通过虚拟内存,操作系统为各个进程提供了独立的内存空间,防止进程间的干扰。这样可以有效避免一个进程意外修改或读取其他进程的数据,从而保护系统的稳定性和安全性。
分页内存 (Paged Memory)
分页内存是现代操作系统管理内存的主要方式。
-
页的概念:在分页内存系统中,物理内存(通常是DRAM)被划分为若干固定大小的块,称为“页”(Pages)。每个页通常为4KiB或更大。
-
从磁盘加载页面:当系统需要访问磁盘上的数据时,整个页面会被加载到内存中。这种做法的原因在于,与其频繁访问磁盘中的单个数据字节,不如一次性加载整个页面,以减少总的磁盘访问次数,从而提高系统性能。
-
地址偏移:由于页面大小通常为4KiB,因此需要12位的地址偏移(page offset)来寻址页面内的所有字节。这意味着虚拟地址的低12位用于页面内的偏移,高位部分用于指定虚拟页号。
-
虚拟页号与物理页号的映射:如果虚拟页和物理页的大小相同,则内存翻译会将虚拟页号(VPN)映射到物理页号(PPN)。例如,一个32位的虚拟地址可以拆分为20位的虚拟页号(用于查找页表)和12位的偏移量(用于定位页内的数据)。然后,通过查找页表将虚拟页号转换为物理页号,形成物理地址。
程序如何访问内存的两种情况 (Translation: How a Program Accesses Memory)
在这个场景中,程序尝试访问两个不同的虚拟地址:0xFFFFFFF004
和0x600000030
。下面我们分别讨论这两个虚拟地址在物理内存中是否存在的情况下,操作系统如何处理。
情况1:0xFFFFFFF004
已经在物理内存中
- 程序执行加载指令,指定虚拟地址(VA):
-
程序执行了指令
lb t0, 0xFFFFFFF004(x0)
,从虚拟地址0xFFFFFFF004
中加载数据。
-
- 计算机将虚拟地址(VA)翻译为物理地址(PA):
-
提取虚拟页号(VPN):系统从虚拟地址中提取高20位,即
0xFFFFF
,作为虚拟页号。 -
查找页表:系统在页表中找到对应的物理页号
1
。 -
构建物理地址(PA):系统将物理页号
1
与虚拟地址的偏移量0x004
结合,生成物理地址1
上的某个位置。
-
- 操作系统从物理地址读取数据并返回给程序:
-
操作系统直接从物理地址
1
读取数据,并将其返回给程序寄存器t0
。
-
情况2:0x600000030
不在物理内存中
- 程序执行加载指令,指定虚拟地址(VA):
-
程序执行了指令
lb t1, 0x600000030(x0)
,试图从虚拟地址0x600000030
中加载数据。
-
- 计算机将虚拟地址(VA)翻译为物理地址(PA):
-
提取虚拟页号(VPN):系统从虚拟地址中提取高20位,即
0x60000
,作为虚拟页号。 -
查找页表:系统在页表中查找
0x60000
对应的物理页号,发现该页面指向磁盘,而不在物理内存中。
-
-
如果物理页面不在内存中:
-
操作系统检测到
0x600000030
对应的页面不在内存中,于是从磁盘加载该页面到物理内存地址2
,并更新页表,将0x60000
映射到物理页号2
。
-
- 操作系统从物理地址读取数据并返回给程序:
-
页面加载完毕后,操作系统从物理地址
2
读取数据,并将其返回给程序寄存器t1
。
-
通过这种机制,操作系统确保即使某些页面初始不在内存中,它也能够在需要时将页面从磁盘加载到内存中,并更新相应的映射,从而继续执行程序指令。
页表是什么样子的?(What Do Page Tables Look Like?)
图中这一页深入介绍了页表的结构和功能。
- 32位虚拟地址空间和4KiB页面:
- 对于一个32位的虚拟地址空间和4KiB的页面大小,整个虚拟地址空间包含
2^32
个地址,分成2^20
个虚拟页号(VPN)。
- 对于一个32位的虚拟地址空间和4KiB的页面大小,整个虚拟地址空间包含
- 每个进程的页表:
- 每个进程都有一个独立的页表,页表的每个条目对应一个虚拟页号。每个条目包含物理页号(或者磁盘地址)以及一些状态位。
- 页表并不是缓存:
- 重要的是要理解,页表不是一个缓存。页表没有实际的数据,它仅仅是一个查找表,用于将虚拟地址映射到物理地址。每个虚拟页号都有一个有效的条目,因此页表的作用更像是一个索引表,而不是存储器。
这一页内容帮助我们理解了页表在虚拟内存管理中的核心作用,并明确了它与缓存的区别。页表通过有效管理虚拟和物理地址之间的映射,为操作系统提供了灵活性和保护功能,使得多个进程可以安全、高效地共享系统资源。
Page Table Details I
操作系统虚拟内存管理职责 (OS Virtual Memory Management Responsibilities)
在操作系统管理虚拟内存的过程中,有几项关键的职责需要重点关注:
- 将虚拟地址映射到物理地址:
- 操作系统通过页表将每个进程的虚拟地址空间映射到物理内存地址。这种映射使得每个进程能够拥有独立的虚拟地址空间,而不必直接访问物理地址,从而提高了系统的安全性和灵活性。
- 同时使用内存和磁盘:
- 操作系统通过在磁盘上存储部分数据,来提供一个比实际物理内存更大的“虚拟”内存空间。这种机制不仅扩展了可用内存容量,还有效管理了较慢的磁盘和较快的DRAM之间的资源调度,保证了系统性能的相对平衡。
- 保护机制:
- 操作系统确保进程之间的内存隔离,防止一个进程意外影响到其他进程的内存数据。通过为每个进程分配专用的“私有”内存,操作系统可以避免一个进程的错误导致系统中其他进程的数据损坏。与此同时,这种隔离还防止用户程序篡改操作系统的内存,确保了系统的稳定性。
使用页表实现保护 (Protection with Page Tables 1/2)
页表在虚拟内存保护机制中起着至关重要的作用:
- 每个进程都有专用的页表:
- 操作系统为每个进程维护一个独立的页表,通过跟踪当前活跃的进程,操作系统能够有效管理各进程的内存映射关系。
- 隔离机制:
- 页表通过为不同进程分配不同的物理页面来实现隔离,这种机制确保了一个进程无法访问其他进程的内存区域,从而避免了不必要的干扰和潜在的安全风险。
- 内存共享的可能性:
- 尽管隔离是默认的保护措施,但在某些情况下,操作系统允许多个进程共享同一个物理页面,例如系统数据或共享库,这样可以有效利用内存资源,避免重复数据占用多个物理页面。
使用页表实现保护 (Protection with Page Tables 2/2)
除了基本的隔离功能外,页表还提供了更高级的内存保护机制:
- 写保护位:
- 页表条目中包含一个写保护位(Write Protection Bit),用于控制页面的写入权限。当这个位被设置时,该页面被标记为“保护”状态,意味着程序无法对其进行写操作。
- 保护作用:
- 写保护位通常用于保护关键的数据区域,如程序代码和系统数据。对于这些受保护的页面,任何尝试写入的操作都会触发异常,操作系统会捕捉到这些异常并进行相应处理,确保系统的安全和稳定。
- 异常处理:
- 当程序试图写入一个受保护的页面时,操作系统会通过异常处理机制阻止这一操作,并采取适当的应对措施。这种机制不仅保护了关键数据,还帮助程序员发现潜在的错误。
通过这些机制,操作系统能够更有效地管理内存资源,同时提供强有力的安全保障,确保系统运行的稳定性和可靠性。
页表存储在内存中 (Page Tables Are Stored in Memory 1/2)(下节内容)
在32位虚拟地址空间和4KiB页面大小的系统中,页表的大小和存储方式至关重要。
- 32位虚拟地址空间,4KiB页面:
- 对于一个32位的虚拟地址空间,每个页表项占用4字节(包括状态位),整个页表的大小为4MiB(2^20个页表项,每个项占4字节)。虽然4MiB相对于4GiB的物理内存来说只占0.1%,但它远远超出可以用于缓存的大小。
- 将页表存储在内存中(DRAM):
- 当前情况下,页表通常存储在主存(DRAM)中。这意味着每次需要翻译虚拟地址时,都需要访问主存中的页表。
- 性能影响:
- 由于页表存储在内存中,这可能导致每次内存访问需要额外的内存访问步骤,即先访问页表,再访问实际的物理内存。这样会导致加载或存储指令(lw/sw)在发生缓存未命中时需要两次内存访问,从而影响性能。
页表存储在内存中 (Page Tables Are Stored in Memory 2/2)
为了减轻上述性能影响,有一些优化措施可以帮助提高内存访问效率。
- 性能优化措施:
- 在DRAM和处理器缓存之间传输块而不是字:通过在DRAM和缓存之间传输更大的数据块,而不是逐字传输,可以减少内存访问延迟,进而提高系统整体性能。
- 使用缓存存储经常访问的页表项:通过使用类似于 TLB 的机制,系统可以缓存经常使用的页表项,从而减少对主存的访问次数。这种机制在后续的讨论中会详细介绍。
总结 (And in Conclusion…)
- 操作系统如何管理资源:
- 操作系统负责管理多个进程的资源,包括共享相同的CPU、内存、I/O设备等。每个进程在自己的虚拟内存空间中运行,操作系统通过页表管理虚拟地址到物理地址的转换。
- 每个进程在虚拟内存中运行:
- 对于每个进程,操作系统通过页表将虚拟地址转换为物理地址。这确保了进程之间的内存隔离,同时允许操作系统高效地管理内存资源。
- 待解决的问题:
- 上下文切换:操作系统如何在多个进程之间切换上下文?
- 页面未找到:如果页面不在内存中,操作系统如何处理?
- 写回或写穿:在缓存中如何处理写操作?
- 缓存与虚拟内存的集成:如何将缓存有效地集成到虚拟内存系统中?