细说硬件虚拟化.docx
- 文档编号:10226641
- 上传时间:2023-02-09
- 格式:DOCX
- 页数:12
- 大小:24.82KB
细说硬件虚拟化.docx
《细说硬件虚拟化.docx》由会员分享,可在线阅读,更多相关《细说硬件虚拟化.docx(12页珍藏版)》请在冰豆网上搜索。
细说硬件虚拟化
细说硬件虚拟化
介绍
从2005年出现双核处理器,到2007年的四核处理器,多核处理器的发展就如同滚雪球一般声势越滚越大。
正当桌面市场考虑该如何来消化这愈发强大的处理能力时,那边的服务器市场却在焦急地等待着2009年八核处理器的到来。
这是因为在服务器上有一种处理器杀手级的应用,它要求处理的能力越强越好,那就是虚拟化。
尽管有关虚拟技术将会带来的好处我们已经听到了不少(资源整合,运行遗留程序,负载均衡以及快捷的部署等等),大多数出版物对虚拟技术的细节描写却往往都很笼统。
在VMWorld2008上,我们采访了几位“虚拟机监控程序(hypervisor)”的架构师。
在这篇文章中,我们将就虚拟化对性能的影响作一番深入的探讨。
性能?
它不是一个无关紧要的问题吗?
现代虚拟技术充其量也就损失了不过几个百分点的性能吗?
在本文中,我们将向你展示,事实和那些有着利益背景的白皮书所要你相信的之间有着很大的不同。
在本文中,我们首先来看一看虚拟技术的基本知识,然后在接下来的几个月里,我们将继续就这一问题展开深入的探讨。
在这篇文章里我们讨论的是“硬件虚拟”,所涉及的有可以使得运行多个诸如VMware的ESX,XEN和Windows2008的Hyper-V这样的虚拟服务器成为可能的技术等。
最近,在我们新的IT门户网站上,我们刊登了一篇有关Thinstall,SoftGrid和其它类似软件的“软件虚拟”的介绍性文章。
这些文章所讲的都是关于虚拟服务器的性能问题,以及如何更好地理解虚拟技术。
硬件,或者机器虚拟与“普通”虚拟之间的比较
从某种程度来说,我们早已经用上了虚拟化技术。
事实上,如果没有现代操作系统提供的虚拟化,我们当中的大多数人的工作效率便不会有如此之高。
一台装上现代操作系统的“原生”的服务器或者工作站在处理如磁盘、处理器与内存这样的系统资源时,就已经用上了虚拟技术了。
举例来说,尽管在一台运行有Windows2003系统的服务器上只装上4GB的内存,但是运行其中的10个软件却认为它们都可以用上属于它们的2GB(或者3GB)的用户态地址空间。
在一个RAID-5的磁盘阵列里也许只有3个磁盘存在,但如果你把它们分了10个卷(或者是逻辑单元),那么看起来就像是机器里装有10个磁盘一样。
或者,在一台服务器上就只有2个处理器,然而它给你的感觉却是5个正在运行的程序仿佛可以在同一时间去完成它们的工作一般。
既然现代操作系统已经为我们提供了这样的虚拟功能,我们为什么还要利用虚拟机监控程序来帮助实现完全的虚拟服务器呢?
一方面,操作系统通过为每个进程分配预选定义好的内存空间,使它们的数据段与代码段相分离这样的手段来保护系统中的进程。
与此同时,所有这些进程之间共享同样的文件,更可以访问某些共享内存,而操作系统的全局配置则对每一个进程都起作用。
在许多场合下,这样的隔离是远远不够的。
如果有一个进程占用了100%的处理器时间,那么它就会使其它的程序的运行慢如蜗牛,——哪怕是现代的操作系统都用上了抢占式多任务技术。
而如果采用纯硬件虚拟技术的话,那么你可以从根本上隔离每个拥有自己的客户操作系统的虚拟服务器,它们之间的通讯只能通过虚拟网络才能实现。
处理器运行特权
要在一台物理机器上创建几台虚拟服务器,就必须引进一种称之为hypervisor的新型的软件层,它的另外一个名称是“虚拟机监控程序”,简称VMM。
它最重要的任务是调节对底层硬件的访问,以保证各个客户操作系统能共享同一台机器。
你可以说VMM就像一个操作系统管理进程和线程那样,来管理位于其上的虚拟服务器(客户操作系统和运行其中的进程)。
要理解VMM是如何工作的,我们必须首先理解现代操作系统的工作原理。
大多数现代操作系统拥有两种工作模式:
核心模式。
在这种模式里,任何处理器指令都可以执行,包括那些处理中断,内存管理等具有“特权”的指令。
当然不用说,操作系统本身便运行这种模式下面。
用户模式。
只有用于计算和处理数据的指令得以执行。
运行在这种模式下面的各种应用程序要使用硬件资源时,只能通过请求系统核心的服务才能完成(系统调用)。
整个一个用户模式和核心模式的安排,乃是建立在内存的分页工作的基础之上的。
(当然,也可以用段寄存器和表的方式来使用内存,但这已经超出本文的讲述范围了。
)在一条特权指令得以执行之前,处理器首先会检查这条指令的来源内存页是否具有正确的2位编码的特权。
00编码的指令具有最高特权的指令。
2位编码的形式允许总共有4种指令权限,11编码表示的则为最低特权的指令。
为了便于说明这个指令权限问题,就像你在本文中看到一样,很多出版物利用了“洋葱圈”图形来形象地表示处理器的2位等级编码。
Ring0是具有最高特权的级别,Ring1次之,而Ring3级就是用户应用程序所在的那一级,在这个级别里没有相应的特权来操作硬件资源。
(尝试加入原文中的插图,但不成功。
不好意思)
软件虚拟下的等级变迁:
客户操作系统的位置已处于Ring1的级别,不再是它原来所在的Ring0级。
等级变迁是一项所有的(软件)虚拟都在采用的技术:
原先运行在Ring0级的操作系统被迁移到了低级别的Ring1级。
这使得VMM可以控制客户操作系统对资源的访问。
它避免了一个客户操作系统把另一个客户操作系统踢出内存,或者客户操作系统绕过VMM直接访问硬件等情况的出现。
虚拟化所面临的挑战
虚拟化的鼻祖,IBMS/370所采用的是一套非常健壮的系统,它允许虚拟机监控程序监控运行其上的所有的虚拟机。
如果虚拟机执行在一个缺乏相应特权的级别,每次它所要执行的指令涉及到了“资源管理”方面的指令,都将会产生一个“陷阱”,换言之,就是一个错误。
这时候,VMM会截取所有这些“陷阱”,模拟相应的指令,从而避免其它的客户操作系统产生意外的问题。
为了提高性能,客户操作系统和VMM的开发者(庆幸的是他们都是IBM的人)努力尝试减少“陷阱”的产生,并减少处理这类“陷阱”所需要的时间。
然而要在32/64位的IntelISA架构上是不可能实现这样的虚拟技术的,原因在于Intel的架构并不会为每一条破坏规则的指令,为VMM产生预期的“陷阱”。
其中的POPF就是这样的一个例子,该指令可以用来禁止或者允许中断的发生。
如果一个身处Ring1级的客户操作系统发出了这个指令,那么x86的处理器所做的仅仅是把它给忽略了,而不会发出什么警告。
结果是如果一个客户操作系统要禁止中断的产生,那么和它的本意截然相反的是,它的要求根本得不到满足,VMM也没有办法来了解当前发生的一切。
一直以来,x86系列处理器都是这个样子:
对VMM来说,它有多达17条指令[1]是无法截取和模拟的。
因此x86处理器是无法采用和早期大型机一样的虚拟技术的。
倒是PowerPC和AlphaISA因为没有这样的缺憾,可以满足经典的虚拟技术的要求。
上面说的仅仅是些简单的历史背景知识。
但是,它可以让我们更好地理解Intel和AMD在它们现在的VT-x和AMD-V虚拟技术里所作的改进。
二进制改编
VMware没有坐等Intel和AMD来解决“x86隐形指令”的问题,它在上世纪末期(1999年)提出了自己的解决方案。
可惜的是,超光子检测器实在是太过昂贵了(译注:
“超光子检测器”典出《星球大战》,指的是一种用来侦测具有隐形能力的宇宙战船。
),VMware只好使用“二进制改编”来截获这些“隐形”的x86指令。
不过和Intel的Itanium从x86到IA64,Transmeta(译注,即全美达公司。
)从x86到VLIW,DigitalFX!
32从Alpha到x86的改变中,以及Rosetta中所使用的二进编改编技术相比,VMware的技术要显得轻巧多了。
它不像上面的这些技术那样需要从一种不同的指令集改编到另一种指令集,它要做的只是从x86到x86的改编。
事实上,在某些特定的场合下,它所做的只是简单地把原始指令复制过来而已。
运行时,VMware会改编客户操作系统核心的相关二进制代码,并把改编的结果存入到被称之为“改编缓存”的存储器中。
VMware并不会改编用户程序的代码,因为它知道,或者说假定这些用户代码是安全的。
因此,就如同在原生环境中运行一样,用户模式的应用程序同样是被直接执行的。
(原文图示)
用户模式的应用程序不会被改编,而是直接执行的。
二进制改编只发生在客户操作系统核心被调用时。
所以,只有客户操作系统核心才会有从x86代码改编到相应要长些的x86代码的改编过程。
你可以说客户操作系统的核心代码实际并没有得到执行。
存在于内存中的客户操作系统核心代码只是二进制改编器的输入源罢了,真正被执行的,且执行环境也变成了Ring1级的已变成了经二进制改编后的核心代码了。
在很多场合下,改编后的核心代码其实就是客户操作系统核心代码的一份拷贝。
当然,会有这样的时候,需要对核心代码进行二进制代码改编,而改编后的代码往往要被原来的代码来的长一些。
如果一个客户操作系统的核心需要执行某些特权代码,二进制代码改编器必须把这些危险的代码改编成“安全”的用户模式下的程序代码。
如果核心要求控制物理硬件资源,那么二进制改编器将对这部分代码进行必要的改编,使之转而操作虚拟硬件资源。
(原文图示)
从x86到x86动态二进制代码改编。
(图示:
VMware[2])
二进制改编所要做的是扫描客户操作系统的核心代码,如果发现某一时刻客户操作系统核心将要有所动作,那么它就用安全代码(虚拟化的)来替换它的原始代码。
我们说“安全”的意思,乃是要保障其它客户操作系统和VMM的安全。
VMware尽量使这种二进制改编带来的性能损失控制在最小范围内。
二进制改编器并不会对二进制指令流有优化动作,经改编后的二进制代码流将会被存放在改编缓存中。
如果恰好原来的代码执行的是一个循环,那么这就意味着对这段代码的二进制改编只要发生一次就够了。
除了起到了改编缓存的作用外,二进制改编缓存还和追踪缓存一样跟踪程序的执行流程。
每一次当核心代码要跳转执行的时候,改编器就得对这样的代码进行改编,而不单是仅仅复制一份它的拷贝。
试想,如果原始的代码跳转距离是100个字节,那么处在改编缓存里的核心代码将跳转的距离很有可能超出这个数字。
因为,改编器在改编时导致代码增长,使得跳转的距离也相应变大。
很明显,和放手让特权指令触发“陷阱”错误,然后再对这些触发的“陷阱”进行处理相比,用“安全”的代码来替换某些原始代码的开销要小得多。
当然,这并不是说,这种虚拟技术的低开销状态是一成不变的。
由于使用了改编缓存,改编带来的额外开销一直被控制在很低的范围内,对性能的影响也越来越小。
但是,二进制改编在面临下面的任务时,也拿不出有效的办法来克服性能的损失:
1、系统调用
2、对系统芯片组和I/O设备,中断和DMA的访问
3、内存管理
4、“怪异而复杂的指令”(自我修改,间接控制流等)
对虚拟技术来说,前三个问题显得特别有意思。
这是因为,即便是对“原生”操作系统而言,最后的那种情况也同样是个不容易解决的难题。
所以,不管是一个操作系统也好,还是多个操作系统(虚拟)也罢,在这个问题上不会有明显的差异。
系统调用
尽管讨论系统核心的书报刊物不少,但是系统核心仍然是一个让人心生疑惑的话题。
一些刊物的描述使人产生这样的一种假象,感觉系统核心就像一个“君主”一样,无时不在后台监视着系统里发生的一切。
这样的理解当然是错误的,否则的它就意味着一个现代操作系统就不能正常工作在一个单线程、单核心的处理器上。
在这样的处理器上,在一个给定的时刻,只能有一个线程可以处活动状态,那么操作系统又怎么可能来完成它的监控工作呢?
核心和其它进程一样,都要从具有多任务处理能力的处理器那里得到执行时间。
它们之间的区别在于,核心能够执行其它普通进程所不能执行的特权处理器指令。
因此,普通(用户模式)进程如果要访问硬件资源,它就需要通过核心的中转才行。
如果它们不这样做,那么处理器就会因此产生一个异常,而处理权就又回到了核心那里。
与此同时,核心调度程序利用时钟中断在后台进行监视,以保证在整个系统中没有哪一个进程会过长地占用(强占)处理器时间。
正因为如此,可以这样说,在极短的时间间隔里,处理器是被强制要求执行操作系统的调度进程的[5]。
因此,一个用户应用程序请求核心提供服务的行为,导致了系统调用的发生。
x86平台为系统调用提供了SYSENTER(或者是SYSCALL)和SYSEXIT这样低延迟的实现方案。
然而这样的系统调用对于虚拟机监控程序(VMM),特别是带有二进制改编功能的VMM来说仍然是一种不小的负担。
如前所述,软件虚拟技术(就像二进制改编器一样)通过降低(32位)操作系统的执行等级(通常是从ring0级降低到ring1级)来实现虚拟化。
问题是,一个SYSENTER指令调用(请求核心服务)会被送到一个带有Ring0级标志的内存页中。
本来在这个位置上应该是操作系统本身的代码,但现在这个指令却被送到了VMM那里。
于是,VMM就必须模仿每一个到达它那里的系统调用,进行代码翻译,然后再把控制权交给此时已经执行在ring1级上经过翻译后的核心代码[3]。
(原文图示)
虚拟机上发生的系统调用远比正常情况下复杂得多
当经过二进制改编后的客户操作系统代码执行完任务后,它会调用SYSEXIT指令来返回到用户应用程序。
然而,因为这个客户操作系统此时运行在ring1级上,它就没有足够的权限来调用SYSEXIT,CPU会因为它等级不够而拒绝执行,VMM就必须模拟客户操作系统所要完成的任务。
很明显,系统调用会带来相当的性能损失。
虚拟机上的一个系统调用,差不多要十倍于原生操作系统上系统调用所需的时间。
下面是VMware的工程师在频率为3.8的Pentium4机器上所测得的数据[4]:
一个发生在原生操作系统上的系统调用需要242个时钟周期。
一个经二进制改编过的,运行在ring1级上的32位客户操作系统上发生的一个系统调用需要2308个时钟周期。
如果有多台这样的虚拟机同时在运行,你会发现与直接运行在硬件上的原生操作操作系统相比较,类似的由系统调用带来的性能损失将不再是一个可以简单地加以忽略的问题了。
I/O虚拟
对许多虚拟化技术来说,I/O始终是个大问题。
如果你的虚拟服务器的处理能力不够,你可以增加CPU,或者使用多核处理器(比如把双核的CPU更换成四核的CPU)。
然而在多数情况下,内存带宽,芯片组以及存储设备这类的主机总线适配卡等设备在各个虚拟机之间是共享使用的,而且对它们进行“升级换代”也要困难的多。
另外,和CPU的情况正好相反,系统中其它的硬件设备在大多数虚拟软件中是被模拟出来的。
这就意味着,每一次对虚拟硬件设备驱动的访问,都将被中转到相应的物理设备驱动中去。
(原文图示)
一台至强3.46GHz的机器正运行在BX芯片组上:
这当然是发生一个虚拟机中的场景
举例来说,如果你仔细揣摸过ESX中的虚拟机的话,你就会发现,和你的当代的CPU协同工作的将是设计优秀的,然却是属于9年前的BX芯片组,而你的储存适配卡如果不是Buslogic的,那么就是LSI的产品。
这也意味着你的硬件产品中所采用的最新的技术,将不会在虚拟机中体现出来。
内存管理
一个操作系统以页面表的方式,把虚拟内存页翻译到物理内存地址上。
所有当代的x86的CPU都已在硬件上实现了对虚拟内存管理的支持。
从虚拟内存翻译到物理内存地址的工作由内存管理单元来完成,即所谓的MMU。
而当前在用的地址是被放在一个叫做CR3的寄存器里的(即硬件页面表指针),其它最常用到的页面表则在页表缓存(即TLB)中被缓存起来。
很清楚,一个运行在虚拟机上的客户操作系统是不可能直接存取真正的页表数据。
事实上,一个由虚拟机模拟的内存管理单元(MMU)生成了可让这个客户操作系统看到的页面表。
这些页面表使得客户操作系统产生了这样一种假象,认为它可以把它的虚拟内存地址直接翻译到物理内存地址,但是,实际上这样的工作是由VMM在背后,在客户操作系统不知情的情况下来完成的。
真正的页面表被隐藏了起来,管理权也落到了VMM的手中,而负责执行这种任务的则依然是硬件上的内存管理单元(MMU)。
是以,在这样的情形之下,真正的页面表中已经包含了由客户操作系统操作的“影子页面表”,再由它把操作系统中的虚拟内存翻译到相应的物理页面。
每一次当客户操作系统修改它的内存页映射时,相应的虚拟MMU模块将会捕捉到类似的修改,并同时对“影子内存表”作相应的修改。
就如你猜测的一样,这个过程会增加很多额外的CPU时钟周期。
依据所使用的虚拟技术的不同,对内存表修改内容的不同,类似的工作所需要的CPU时钟周期将比原生操作系统多出3到400倍左右。
其结果是,如果有内存操作频繁的程序运行,那么由管理内存所引起的性能损失,将会是你因使用虚拟化而付出的最大的性能代价。
泛虚拟化
从本质上讲,泛虚拟化和“二进制”改编没多少区别。
“二进制”改编是在代码执行时,现场对某些“重要的”或者“不安全的”代码进行改编,而泛虚拟化则将这样的改编过程放到了源代码当中。
当然,相比于在执行现场改编二进制代码,在源代码中进行相应的修改所带来的灵活度就大大境加了,而前者对改编的速度要求太高了。
和二进制改编比起来,泛虚拟化技术的另一个优势是,它可以大大减少由VMM设置的“陷阱”。
虚拟机监控器为关键的核心服务,如内存管理,中断处理以及时钟监视等,提供了一组所谓的“虚拟机系统调用”。
这些虚拟机的系统调用只会在必要的时候才发生。
举例来说,大多数的内存管理工作是由各个不同的客户操作系统来完成的,只有当需要更新页表数据或者要访问DMA资源时,这样的虚拟机系统调用才发生并送交虚拟机监控器来处理。
(原文图示)
从前端驱动接口到后端的基于Linux的驱动之间的联系的简化图
在Xen的虚拟化的实现中,最精彩的地方是对I/O的处理方式。
在它的虚拟机里,I/O设备仅仅是这样的一些连往一个具有特权的虚拟机(在Xenk也被称为域0)中原生的设备驱动的简洁的接口。
这就意味着这里不再有往常的模拟层,系统的性能得以大大的提高。
由VMwareESX身上体现出来的品质,Xen所带来的改进并非是名实不符的广告宣传:
与运行在早期版本的ESX上的虚拟机低下的网络性能相比,在ESX3.x上已经获得了相当不错的网络表现,而这样的改进要归功于一个实现的相当巧妙的泛虚拟的,被称之为vmxnet的泛虚拟网络驱动。
一句话,泛虚拟化是一种非常优秀的虚拟化技术,它能够彻底消除由二进制改编带来的性能损失,大幅改进I/O驱动的性能,同时也可以减轻由系统调用所带来的性能损失。
当然,频繁的中断以及系统调用同样会给整个系统带来负面影响。
我们将在以后的文章里详细探讨Xen。
泛虚拟化最大的缺点是:
1、如果你只用泛虚拟化技术,那么你就不能使用未经修改的客户操作系统。
2、64位的客户操作系统只能运行在非特权的Ring3上[6]。
(原文图示)
泛虚拟化并不能很好的处理64位的客户操作系统
为了保护操作系统,页表的切换是必须的,这看起来好象并不是个严重的问题。
但这样的结果是将会产生两个系统调用和一次TLB的刷新,它们是非常费时的。
让我们来看看Intel的VT-x和AMD-V是如何解决这个问题的。
而虚拟化技术带来的好处显而易见的,更低的成本、能耗、维护费用,更灵活的资源配置管理。
节省资金
我在这里举一个例子:
你刚刚为你的5台新服务器购买了5个WINDOWS2003许可证,计划投入到公司的基础架构之中,这大概将花费掉你1万到1万5千元的许可证费用。
如果我告诉你,我能够让你花费2000到5000美元就得到同样的基础架构,你相信吗?
你可能急于知道怎么实现?
非常简单,你只需要购买一个WINDOWSServer2003R2许可证,你就免费获得了最多四个虚拟化实例,这样你完万能下载喜欢的所有虚拟化软件,再免费安装四个虚拟化操作系统。
整合服务器
非常多主机托管中心及企业服务器机房都是设备林立。
特别是在托管机房中,似乎每一个厂商都需要独立的服务器来运行其独特的软件,在.com时代就是这样运作的,不过今天为了给这些机器供电,我们面临不断增长的能源成本压力。
确实,在今天这个技术的太平盛世,服务器机房是能源的“吸血鬼”。
企业怎么面对这个不断增加的成本压力呢?
首当其冲的解决之道就是虚拟化。
为了智能整合的第一步,也是最简单的一步,就是列出所有服务器和软件的周详目录,观察一下有多少服务器只是运行着单一的一种应用--甚至有的还是在运行着一个以往遗留下来的应用。
通过虚拟化,你将有可能将20台服务器的应用整合到5台!
最大化利用率
最大化服务器利用率和整合服务器是相关联的,你不可能做其中之一而不考虑另外一个。
服务器什么时候被整合,什么时候其利用率问题才有可能得到解决。
深入到服务器实际应用场景去考察一圈,你会发现非常多具有两个甚至四个处理器的服务器上面只运行着一个非常小的应用软件,这些服务器的使用情况甚至没有被注册登记。
实际上,这些系统如果将潜力全部发挥出来的话,能装载得下三到五个虚拟实例。
目前,将所有的传统应用软件聚集起来,放置到一台具有几个虚拟实例的服务器上,已不是什么罕见的事情。
确实,通过虚拟化充分利用现有的服务器资源,不仅能使你削减成本,而且还能有效整合你应用场景中的服务器。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 细说 硬件 虚拟