概览:
●内存管理和 SMB 2.0
●NTFS 自修复功能、Windows 硬件错误报告体系和驱动程序验证程序
●I/O 完成端口、线程池和 NUMA 的可伸缩性
●Hyper-V 虚拟化
Windows Server 2008 是最新版本的 Microsoft 服务器平台,它包含许多系统级更改,这些更改涉及操作系统的所有功能领域:从内存管理到线程调度,从网络连接到安全(这里只列出了少数几个)。
由于 Windows Server® 2008 和 Windows Vista® SP1 的内核相同。只有其中的少数功能仅特定于客户端且并未包含在 Windows Server 2008 中,如 SuperFetch、ReadyBoost、ReadyDrive、ReadyBoot 和多媒体类计划程序服务 (MMCSS)。
因此,我将不再重复介绍 Windows Vista 中已介绍过且 Windows Server 2008 中同样包含的重要内核变化,如 I/O 优先级排列、新的引导体系结构 BitLockerTM、代码完整性和强制完整性级别。我将重点介绍之前这些文章中未涉及到的关键变化,包括与可靠性、性能、可伸缩性以及新的 Microsoft 管理程序计算机虚拟化技术 Hyper-VTM 相关的变化。
同样,与之前的文章一样,本文的范围仅限于操作系统内核 Ntoskrnl.exe 以及与其紧密关联的系统组件的变化。例如,本文不会介绍安装(WIM 或 Windows® 映像格式和基于组件的服务)、管理(组策略和 Active Directory® 改进)、常规诊断和监控(Windows 诊断基础结构)、核心网络(新的防火墙和 TCP/IP 实现)、Server Core 或服务器角色的变化。
用于多处理器系统
系统的其中一项底层变化是 Windows Server 2008 仅提供设计用于多处理器系统的内核版本。过去,Windows 拥有专门针对单 CPU 计算机上的单处理器的版本,因为该版本可通过忽略仅在多处理器环境下需要的同步代码来获得稍好一点的性能。随着硬件速度变得越来越快,由优化带来的性能提高几乎可忽略不计,并且如今的大多数服务器系统都包含多个处理器,所以已不再需要单处理器的内核版本。
Windows Server 2008 内核的各个版本,系统中具体使用哪个版本取决于操作系统是调试版本(Checked 版本)还是零售版本、安装为 32 位还是 64 位(Itanium、Intel 64 或 AMD64),以及如果是 32 位安装,系统的物理内存是否超过 4GB 或支持数据执行保护 (DEP)。Windows Server 2008 还可能是最后一个提供 32 位版本的 Windows Server 操作系统。
内核 32位64位 多处理器是是 多处理器Checked版本是是 多处理器物理地址扩展(PAE)是否 多处理器PAEChecked版本 是否 |
内存管理
试验:查看大规模的磁盘 I/O 操作
可使用 TechNet Sysinternals Process Monitor之类的文件系统监视工具来查看 Windows Server 2008 系统上的大规模文件 I/O 操作。
有多种方法均可产生大规模 I/O 操作。如果有另一个运行 Windows Vista Service Pack 1 或 Windows Server 2008 的系统,可在头一个服务器上运行 Process Monitor 并监控到第二个系统的文件复制。还可以通过运行非常耗费内存的程序使得内存管理器将页面写出到分页文件中,从而产生大规模的分页文件 I/O 操作。
图 A 显示了在 Windows XP 系统中运行非常耗费内存的程序后 Process Monitor 的输出,此时在 Process Monitor 的“Options”(选项)菜单中选中了“Enable Advanced Output”(启用高级输出)选项,并将过滤器设置为仅显示到分页文件 pagefile.sys 的写入。“Detail”(详细信息)列显示写入大小为 64KB。
图 A
如果在 Windows Server 2008 上运行相同的步骤,则很可能出现类似图 B 中显示的输出,它显示大多数写入大小约为 1MB。
图 B
Windows Server 2008 中的内存管理器包含多项性能增强功能。例如,与 Windows Server 2003 相比,从分页文件提取数据或对映射文件执行预读 I/O 时,它将使用数量更少但规模更大的磁盘 I/O。I/O 系统中的变化是促成更大规模的文件 I/O 的前提,它去除了自 Windows NT® 的第一个版本以来一直存在的 64KB 的 I/O 大小限制。
并且,必须注意:与 Windows Server 2003 相比,使用 Windows Server 2008 时,Cache Manager 从映射文件进行预读(猜测性读取)的数据读取通常要大两倍,并且将直接进入待机列表(系统的代码和数据缓存)。这种行为取代了 Cache Manager 映射虚拟内存并将数据读入系统工作集(由内存管理器为系统分配的内存)的需要,而这种需要可能导致其他使用中的代码或数据被不必要地驱出工作集。
当把数据写入分页文件时,内存管理器也会执行更大规模的 I/O。尽管 Windows Server 2003 常常执行比 64KB 还小的写入操作,但在 Windows Server 2008 中,内存管理器通常使用 1MB 的写入操作。
除通过减少写入分页文件的次数来提高性能外,较大规模的写入操作还可减少分页文件中的碎片。而它又反过来减少了读回多个页面所需的读取次数和磁盘寻道次数,因为如果不相邻,读取和寻道次数都会多得多。
内存管理器还会尝试写出其他已修改页面(这些页面与将要写出到所拥有进程的地址空间中的页面相邻),并且会将分页文件放到已包含其他相邻页面的区域中。这种方法也可尽量减少碎片并提高性能,因为那些可能会最终写出到分页文件中的页面均已被写入。此外,它还减少了引入大量相邻进程页面所需的分页读取次数。查看侧栏“试验:查看大规模的磁盘 I/O 操作”了解有关内存管理器使用大规模的 I/O 方面的更多信息。
SMB 2.0
自从文件服务功能被引入到 Windows 中以来,服务器消息块 (SMB) 远程文件系统协议(也称为通用 Internet 文件系统 (CIFS))就已成为 Windows 文件服务的基础。在过去的几年中,SMB 的设计限制制约了 Windows 文件服务的性能和利用新的本地文件系统功能的能力。例如,单个消息能传输的最大缓冲区大小为约 60KB,并且 SMB 1.0 无法识别 Windows Vista 和 Windows Server 2008 中新增的 NTFS 客户端符号链接。
Windows Vista 和 Windows Server 2008 引入了 SMB 2.0,它是客户端和服务器都支持时 Windows 所使用的一种新型远程文件服务协议。除能正确处理客户端符号链接和其他 NTFS 增强功能外,SMB 2.0 还使用批处理来最小化客户端和服务器之间的信息交换数量。批处理可提高广域网 (WAN) 之类高延迟网络的吞吐量,因为它允许同时传输更多数据。
SMB 1.0 针对单个文件按顺序执行 I/O,而 SMB 2.0 则实现了 I/O 管道,从而可针对同一文件执行多个并发 I/O。它通过衡量客户端用于未完成 I/O 的服务器内存数量来决定管道的深度。
由于 Windows I/O 内存管理器和 I/O 系统以及 TCP/IP 接收窗口自动调节方面的变化和文件复制引擎的改进,SMB 2.0 显著提高了吞吐量并减少了大型传输的文件复制时间。由于两种操作系统都实现了 SMB 2.0,所以部署 Windows Server 2008 文件服务器和 Windows Vista 客户端即可使用 SMB 2.0 并实现这些性能优点。
使用 NTFS 自修复功能提高可靠性
可靠性是一个关键服务器属性,Windows Server 2008 提供各种改进来帮助管理员顺畅运行其服务器(包括在线 NTFS 一致性修复、新的硬件错误报告体系以及对驱动程序验证程序的扩展)。
由于现在使用的存储设备一般都以 TB 为单位,因此对某个卷进行脱机一致性检查可能会使服务中断数小时。鉴于许多磁盘损坏都局限于单个文件或部分元数据,Windows Server 2008 实现了新的 NTFS 自修复功能,即可在卷保持联机的情况下修复损坏。
当 NTFS 检测到损坏时,它将阻止访问受损的文件并创建一个系统工作线程,该线程将对受损数据结构执行类似 Chkdsk 的修复,完成后再允许访问修复后的文件。在此操作期间仍然可以正常访问其他文件,因而最小化服务中断。
WHEA 基础结构
Windows Server 2008 中包含有 Windows 硬件错误报告体系 (WHEA) 基础结构,它可以简化硬件故障管理并主动响应非致命错误。服务器通常都有严格的正常工作时间保证,因此及时确定并响应此类系统中的错误至关重要。
通过对利用在线崩溃分析 (OCA) 提交到 Microsoft 的崩溃进行分析表明:约 10% 的操作系统崩溃是源于硬件故障,但确定此类崩溃的根本原因却非常困难甚至于不可能,因为崩溃时所获取的硬件错误信息非常少。此外,在 Windows Server 2008 之前,Windows 并不内置支持监控设备的运行状况,也未实现故障前的修复或通知。其原因在于硬件设备并未使用一种通用的错误格式并且不支持错误管理软件。
WHEA 为各种平台设备(包括处理器、内存、缓存和类似 PCI 和 PCI Express 之类的总线)提供了统一的错误源发现和报告机制。其原理是实现图 2 中所示的体系结构,其中核心是错误源调用来报告错误的内核 API。此 API 要求所有错误都以同一方法进行格式化,然后使用 Windows 事件跟踪 (ETW) 事件来记录错误(严重错误则在重启后再记录)。
图 2 WHEA 错误报告基础结构
ETW 早在 Windows 2000 中就已引入,而当 ETW 使用 WHEA 后,硬件制造商和软件供应商就可轻松地开发利用 WHEA 事件的设备诊断管理应用程序。如果某事件已严重到足以导致系统崩溃,WHEA 会确保将该致命错误记录存储到崩溃转储文件中,这样管理员就可确定崩溃的根本原因。
WHEA 的另一关键部分是位于 %Systemroot%\System32\Pshed.dll 中的平台特定的硬件错误驱动程序 (PSHED)。内核与 PSHED 链接,而它与平台和固件硬件连接,实质上是用作错误通知和 WHEA 错误报告 API 之间的转换层。Microsoft 为每种平台体系结构(x86、x64、Itanium)提供有一种 PSHED 并且 PSHED 公开了插件模型,所以硬件供应商和制造商可使用特定于其平台的行为来覆盖默认行为。
最后,与其他错误源相连的系统组件 — 包括设备驱动程序、硬件抽象层 (HAL) 和内核 — 可实现底层硬件错误处理程序 (LLHEL)(它将首先处理错误状况)。LLHEL 的工作是从设备中提取错误信息,通知 PSHED 允许其收集其他平台错误信息,然后调用内核的 WHEA 错误报告 API。
驱动程序验证程序
从 Windows 2000 起,每个 Windows 副本中都包含有驱动程序验证程序,它是一个用于跟踪出错的设备驱动程序和故障硬件的强大工具。管理员通常将驱动程序验证程序(%Systemroot%\System32\Verifier.exe) 配置为密切监控可能导致系统崩溃的可疑设备驱动程序的行为。驱动程序验证程序可捕获非法驱动程序操作,这样崩溃转储文件就可以直接指出罪魁祸首。
之前驱动程序验证程序的缺陷在于大多数配置更改都需要重新启动系统,而生产服务器明显不愿出现这种情形。Windows Server 2008 中的驱动程序验证程序通过取消最有用验证的重启要求而改进了这一过程,因此可在不重新启动系统的情况下对出现问题的服务器进行故障排除。
此外,驱动程序验证程序还引入了三种新的验证(如图 3 所示)。安全检查确保设备驱动程序在用于与应用程序连接的对象上设置了安全权限。强制挂起 I/O 请求测试了驱动程序对于需立即完成而非一段延迟后再完成的异步 I/O 操作的恢复能力。杂项检查则确认驱动程序有无错误释放使用中的资源、错误使用 Windows 管理规范 (WMI) 注册 API 以及泄漏资源处理程序。
图 3 选中 Windows Server 2008 选项的驱动程序验证程序
可伸缩性
可伸缩性是指操作系统或应用程序有效利用多个处理器和大量内存的能力。Windows 的每个版本都会通过减少或取消使用锁(它们会降低多处理器的平行性)来提高可伸缩性,Windows Server 2008 也不例外。
执行计时器超时的代码中有一个较小但却非常重要的改进,即不再需要调度程序锁(所有底层同步操作都会使用的一种系统范围调度程序锁)。从而降低了 CPU 同步开销,使得 Windows Server 2008 终端服务器系统能比 Windows Server 2003 多支持约 30% 的并发用户。
Windows Server 2008 中的其他可伸缩性改进包括完成端口增强功能、新的线程池实现、更加有效地使用非一致内存访问 (NUMA) 硬件以及动态系统分区。
改进了 I/O 完成端口处理
大多数可伸缩的 Windows 服务器应用程序(包括 IIS、SQL Server® 和 Exchange Server)都依靠称为完成端口的一个 Windows 同步 API 来最大程度减少执行 I/O 操作时在多个线程之间的切换。具体方法是首先将新到请求(如 Web 服务器客户端连接)通知与完成端口关联起来,并指定一个线程池来专门等待通知。当请求到来时,Windows 将调度一个线程,该线程通常执行其他 I/O 操作(如从磁盘读取一个网页并将其发送到客户端)来完成该请求。
因此,相同线程可尽快地返回以等待更多的客户端请求,线程异步执行 I/O 并将 I/O 完成与完成端口关联起来。线程随后返回等待完成端口,当新请求到来或某个 I/O 完成时,完成端口将调度该线程。通过这种方式,同一线程在 CPU 上始终处于活动状态:处理客户端请求或等待完成端口。
之前 Windows 版本中完成端口的缺陷在于:当 I/O 完成后,I/O 系统将让执行该 I/O 的线程立即执行一小段完成处理,而不考虑该线程当前正在执行的其他工作。如果还有其他线程处于活动状态,则常常会导致调度程序抢占活动线程,并上下文切换到另一个执行线程的情况。
通过将完成处理延迟到下一线程以等待与该 I/O 关联的完成端口,Windows Server 2008 避免了此类上下文切换。因此,即使还有另一线程正在等待完成端口,它仍会在执行其他代码之前先执行完成处理,而且调度程序不必切换到执行线程。这种最小化上下文切换的能力可显著地改善高负载服务器应用程序的可伸缩性。
线程池更加有效
利用多个 CPU 来写入应用程序非常困难,因此 Windows XP 引入了工作线程池,它是一种基础结构和相关 API,用于提取在多个 CPU 间执行小段工作的详细信息。 应用程序将工作项目指定给线程池 API,然后该 API 在它为系统中的每个 CPU 创建和管理的某个线程中执行这些工作项目。
线程池的目的是通过使用相同的线程连续执行多个工作项目来尽可能减少上下文切换。当某个线程因为忙于执行其他工作而无法达到此目的时,它将使用不同 CPU 上的另一线程来执行该工作项目。
Windows Server 2008 的线程池实现可间接地(受益于完成端口改进)和直接地(通过优化线程管理)更好利用 CPU,这样工作线程就能根据需要动态切换以便处理应用程序的负荷。并且,此基础结构的核心已转移到内核模式,从而最小化使用该 API 的应用程序所产生的系统调用数量。最后,新 API 使应用程序能够更轻松地执行某些操作,如在应用程序关闭期间中止已排队的工作单元。
NUMA 优化
Windows Server 2003 在线程调度程序和内存管理器中引入了 NUMA 优化,而 Windows Server 2008 在 I/O 管理器中添加了 NUMA 优化同时扩展了内存管理器的 NUMA 优化。
NUMA 系统通常是多处理器系统,其中的内存延迟随访问它的处理器不同而有所不同(请参见图 4)。内存被分成多个节点,CPU 和节点之间的延迟可能各不相同,并且每个 CPU 都被视为它可最快访问的那个节点的一部分。
图 4 示例 NUMA 系统
NUMA 系统(尤其是具有超过八个 CPU 的系统)通常比一致内存访问系统更加经济且性能更高。一致内存访问系统必须平等地为所有 CPU 提供内存,而 NUMA 系统则能够为直接连接到 CPU 的内存提供高速互连,同时为与 CPU 相隔较远的内存提供较为便宜但更高延迟的连接。
为能在 NUMA 系统中有效扩展,操作系统或应用程序必须了解节点拓扑结构,以便使计算能够在包含计算数据和代码的内存附近执行。例如,Windows 调度程序为每个线程分配一个所谓的理想处理器,该处理器是调度程序试图始终在其上执行该线程的 CPU。这样做可以使线程置于 CPU 缓存中的数据能够尽可能地在每次该线程运行时可用。
在 Windows Server 2003 中,调度程序扩展此概念的方法是:将包含理想处理器的节点视为该线程的理想节点,并且当理想处理器正忙于执行另一个线程时,调度程序会尝试在理想节点中的另一个 CPU 上调度该线程。Windows Server 2003 内存管理器也支持 NUMA,并且在可能的情况下,它会将线程的内存分配定向到正在执行此线程的节点的内存中。
在 Windows Server 2008 中,内存管理器将内核的非分页内存缓冲区(内核和设备驱动程序用于存储必需保存在 RAM 中的数据的内存)分到各个节点,这样可以在产生分配的节点上为线程分配内存。系统页表项 (PTE) 是从发生分配的节点中分配,如果需要新页表页来满足内存分配,则会按照在 Windows Server 2003 中所采取的方式在相同的节点内存中分配,而不会从任何其他节点的内存中分配。
在 Windows Server 2003 中,当线程进行内存分配时,内存管理器在分配内存时将优先考虑在线程当前执行的节点中进行分配。如果线程暂时调度到非理想节点,则在此期间执行的所有分配操作都将在非理想节点中执行。所以,当线程最终回到其理想节点中执行时,它将不再像最初一样紧挨着所分配内存中存储的数据或代码。
为解决这一问题,在 Windows Server 2008 中,内存管理器在所有线程内存分配时都将优先考虑线程的理想节点,即使线程正在另一节点附近执行。内存管理器还能自动了解处理器和节点之间的延迟,所以当理想节点中没有足够的可用内存时,它会检查与理想节点最近的另一节点。此外,当线程引用代码或数据时,内存管理器将把其待机列表中的页面迁移到线程的理想节点。
希望控制分配位置的应用程序可使用新的 NUMA 内存 API,它使这些应用程序能够为内存分配、文件映射视图和文件映射对象指定首选节点。对于与文件映射相关的分配,内存管理器会检查映射操作是否指定节点,然后检查文件映射对象是否指定节点,如果两者都未指定,则最后它将回来继续选用线程的理想节点。
在 Windows Server 2008 之前,用于存储或网络 I/O 的中断及其相关的延缓进程调用 (DPC) 能够在任意 CPU 上执行,包括在与启动 I/O 操作处于不同节点的 CPU 上执行。这有可能导致 I/O 操作中的数据读取或写入在访问数据的节点以外的其他节点的内存中执行。
为避免这种情况,Windows Server 2008 I/O 系统将 DPC 执行定向到启动 I/O 操作的节点中的 CPU,并且拥有支持 PCI 总线 MSI-X(消息信号中断标准的扩展)设备的系统还可以通过使用设备驱动程序来进一步让 I/O 在本地完成,因为这些设备驱动程序将利用 Windows Server 2008 API 将 I/O 中断定向到启动该 I/O 的处理器。
动态分区
让系统更具伸缩性的一种方法是让其支持动态增加硬件资源(如 CPU 和内存)。如果这些资源无需重启系统即可实现更换,则此支持还能使系统更具可用性。
Windows Server 2003 支持动态内存添加功能,从而使得具有动态内存支持的服务器能在管理员添加的同时即可使用这些 RAM。Windows Server 2008 还扩展了动态内存支持,因为它可实现内存更换。
RAM 由于越来越依赖纠错码 (ECC) 校正而非常容易发生故障,因此在支持动态更换的服务器上,Windows Server 2008 可透明地将出现故障的内存条中的数据迁移到替换内存上。具体过程为:首先迁移操作系统所控制的数据,然后将硬件设备置于低功耗状态来有效关闭它们,迁移内存中的剩余数据,接着恢复设备电源继续正常操作。
Windows Server 2008 还支持处理器的动态添加和动态更换。对于动态更换,硬件必须支持备用 CPU 概念,当现有 CPU 产生故障指示时,备用 CPU 可联机或动态添加到系统中,目前仅高端系统支持此概念。Windows Server 2008 调度程序可减缓故障 CPU 上活动的速度,并将工作转移至替换硬件上,随后可取出故障 CPU 并将其更换为新的备用件。
Windows Server 2008 支持处理器的动态添加,因此管理员能在不停机的情况下升级服务器的处理能力。但是,调度程序和 I/O 系统只能将新 CPU 提供给那些通过新 API 请求 CPU 到达通知的设备驱动程序和应用程序,因为某些应用程序内置假定 CPU 数量对于引导会话而言是固定的。例如,应用程序可能为每个 CPU 分配一个工作队列,线程执行时将使用与该 CPU 关联的队列。如果调度程序将该应用程序的某个线程调度到新的 CPU 上,它可能会试图引用并不存在的队列,因而可能导致损坏应用程序的数据并很有可能致使该应用程序崩溃。
基于 Microsoft 服务器的应用程序(如 SQL Server 和 Exchange Server)能支持 CPU 动态添加,一些核心 Windows 进程也支持此功能,包括 System 进程、会话管理器进程 (%SystemRoot%\System32\Smss.exe) 和 Generic Service Hosting 进程 (%Systemroot%\System32\Svchost.exe)。其他进程也可使用 Windows API 来请求新 CPU 到达通知。当新 CPU 到达时,Windows 将向设备驱动程序通知这一情况、启动 CPU 并随后通知所写入的设备驱动程序和应用程序使用新的 CPU,这样它们就可以在需要时分配数据结构以跟踪新 CPU 上的活动。
计算机虚拟化
在 Windows Server 2008 之前,Microsoft 就已经使用宿主虚拟化技术(如图 5 所示)实现了包括 Virtual Server 2005 在内的各种虚拟化产品。在宿主虚拟化中,虚拟机的实现技术是在宿主操作系统上(通常是作为设备驱动程序)运行的虚拟机监控器 (VMM)。VMM 依赖宿主操作系统的资源管理和设备驱动程序,并且当宿主操作系统调度其运行时,它会在活动虚拟机 (VM) 之间对 CPU 切分时间片。
图 5 宿主计算机虚拟化
Hyper-V(以前的代号为“Viridian”)是利用管理程序虚拟化得以实现的。管理程序完全控制着所有硬件资源,甚至引导系统和用于控制 VM 的 Windows Server 2008 操作系统本身实质上也是以虚拟机的方式运行(如图 6 所示)。
图 6 Hyper-V 体系结构
管理程序可将系统分成多个 VM,并将 Windows Server 2008 的引导实例当作主分区(或根分区),以使其可直接访问各种硬件设备(如磁盘、网络适配器和图形处理器)。管理程序要求根分区执行电源管理并响应硬件即插即用事件。它将截取子分区中启动的硬件设备 I/O 并将其路由到根分区,然后根分区使用标准 Windows Server 2008 设备驱动程序来执行硬件访问。通过这种方式,运行 Hyper-V 的服务器可以充分利用 Windows 对硬件设备的支持。
当将 Windows Server 2008 配置为具有 Hyper-V 服务器角色时,Windows 将把 hypervisorimagelaunchtypeboot 引导配置数据库 (BCD) 设置设为 auto,并将 Hvboot.sys 设备驱动程序配置为在引导过程的前期启动。如果配置了该选项,Hvboot.sys 将使系统做好虚拟化准备,然后将 %Systemroot%\System32\Hvax64.exe 或 %Systemroot%\System32\Hvix64.exe 加载到内存中,具体加载哪个程序取决于系统是实现 AMD-V 虚拟化扩展还是 Intel VT CPU 虚拟化扩展。
加载完成后,管理程序使用虚拟化扩展将自身插入到 Windows Server 2008 中。用户模式的应用程序使用 x64 处理器的 Ring 3 权限级别,而内核模式代码则在 Ring 0 上运行,因此管理程序实际是在概念权限级别 Ring -1 上运行,因为它可控制 Ring 0 上运行的代码的执行环境。
当使用 Hyper-V 管理控制台创建或启动子分区时,它将利用 %Systemroot%\System32\Drivers\Winhv.sys 驱动程序来与管理程序通信,该驱动程序使用公开记录的 hypercall API 来指示管理程序创建指定物理内存大小的新分区和执行特征。根分区中的 VM 服务 (%Systemroot%\System32\Vmms.exe) 为每个子分区创建一个 VM 工作进程 (%Systemroot%\System32\Vmwp.exe) 以管理子分区的状态。
Windows 改善子 VM 操作系统性能的其中一种方法是 Windows Server 2008 和 Windows Vista 都已实现的启发方法(即仅当操作系统运行实现 Microsoft hypercall API 的管理程序时才会激活的代码序列)。通过直接请求管理程序的服务,子 VM 避免了在管理程序必须猜测子操作系统的意图时所产生的虚拟代码开销。
例如,未实现自旋锁(执行底层多处理器同步)启发方法的来宾操作系统将停在一个紧凑循环上旋转以等待其他虚拟处理器释放自旋锁。此旋转可能会阻塞其中一个硬件 CPU,直到管理程序调度第二个虚拟处理器。在启发式操作系统中,自旋锁代码会在将要发生旋转时通过 hypercall 通知管理程序,这样管理程序可以立即调度另一个虚拟处理器并降低不必要的 CPU 使用。
Windows Server 2008 改善 VM 性能的另一种方式是加速 VM 对设备的访问。可通过在子操作系统中安装统称为“VM 集成组件”的一个组件集合来增强性能。
如果运行未安装集成组件的 VM,则子操作系统将为管理程序所提供的模拟设备配置硬件设备驱动程序。当设备驱动程序试图使用硬件资源时,管理程序必须进行干预以便通知根分区,根分区将代表子 VM 操作系统使用标准 Windows 设备驱动程序执行设备 I/O。由于单独的高级 I/O 操作(例如读磁盘)可能包含多个离散的硬件访问,所以它可能导致管理程序和根分区中出现许多称为“截取”的转换。
Windows Server 2008 使用以下三种组件来最小化截取:虚拟机总线驱动程序 (%Systemroot%\System32\Drivers\Vmbus.sys)、虚拟服务客户端 (VSC) 和虚拟服务提供商 (VSP)。当利用受支持操作系统将集成组件安装到 VM 中时,VSC 将取代设备驱动程序的角色,并使用子 VM 中的 Vmbus.sys 驱动程序服务,通过管理程序的 hypercall 和内存共享服务将高级 I/O 请求发送到根分区中的虚拟机总线驱动程序。在根分区中,Vmbus.sys 将请求转发到相应的 VSP,然后它通过根分区的设备驱动程序来启动标准 Windows I/O 请求。