用“忙碌度”来度量设备虚拟化的性能

本文讨论设备性能的一般度量方法,并根据性能判断的基准点是否确定唯一,将设备性能分为外部性能内部性能 两类。

外部性能

我们采用很多方法来量化一个设备的性能,一般是横向比较,也就是运行一些基准测试软件来获得针对指定设备的测试成绩,作为度量设备性能的量化数据。但是,如果只有单个设备的量化成绩,其实作用不大。100分的成绩,对应的性能到底为高、中或低,需要和更多的设备进行横向比较,才能体现出来。业界会针对某类设备,设立若干个性能相关的标杆基准点,来判别不同的量化分数所对应的性能级别。值得注意的是,这个所谓的标杆基准点,可能是有形的数字,但更可能是无形的,由一些评测实验室在他们的评测报告中体现,当一款新的旗舰设备隆重上市后,旧标杆将随之被修正。

换句话说,通过横向比较为来判断性能时,在不同的时间,比较和判断的标杆基准点很可能是不同的。如果你淘了一块心仪已久的两年前的旗舰显卡,欣欣然准备要大显身手的时候,重新评估一下这块显卡在今天的性能地位,发现已经掉档到入门级别了,你可能会大失所望吧。设备本身的性能并未改变,变化的是评判的标准。

硬件生产工艺的进步,会带来设备性能的大幅提升,特别是摩尔定律还在发生作用的年代,这个提升的幅度是指数级别的,非常惊人。影响性能成绩的另一个因素,是测试软件自身的代码演进和优化程度。一个并不罕见的情况是,使用不同的基准测试软件,对不同的设备进行测试,如果这些设备在市场上的目标定位相同,最后的测试成绩很可能互有参差,而不是一边倒地断定出孰优孰劣。在某个测试软件中,A产品领先一些,另一个测试软件中,B产品则略胜一筹。还有一种情况是,将某个基准测试软件版本升级之后,重新测试某产品,可能会发现结果大不相同。再比如,同一块显卡上,使用不同的3D编程接口(如OpenGL、DX或其它),在渲染相同的内容时,性能也可能不同。这是3D编程接口需要不断迭代升级的一个原因,如何通过优化自身的结构,来更好地发挥硬件的有限性能。

软件的编程方式和优化特性的选择,对不同的设备会产生不同的性能表现。

这种通过外部横向比较而产生的性能数据和判断依据,称为外部性能。其典型特征是:性能的判断依据不断变化——主要地,其性能基准点不断地被提高。

内部性能

继续阅读

112 total views, 1 views today

GVT-G虚拟GPU的性能

如果把一块显卡设备的极限运能定为100,用户在日常使用中,除非一直进行图形渲染、玩3D游戏或进行相关的科学计算,而只是日常使用,浏览网页或运行办公软件之类,平均下来,显卡的运能可能只发挥了20分左右。系统使用者的日常作业,远远无法满足硬件的极限运能。这种时候,如果使用GPU虚拟化技术,就会存在很多的应用场景,能够成倍地提高使用效率,尽可能地逼近设备的极限运能。如果单系统对显卡的使用率为20%,那么如果有能力同时为5个或更多的系统提供虚拟化设备,理论上,就有可能逼近100%的运能极限。这很像现在社会上流行的共享单车,一辆单车可以在不同的时段被不同的人使用,很像分时复用的社会化实现,从而极大地提高了单车的使用效率。

虚拟化性能

GPU虚拟化到底效率如何,需要有工具提供衡量的依据。在GVT项目组内部,现在使用两种方式来量化GVT的效率。第一种是运行各种Benchmark工具,通过所得分值来衡量虚拟GPU在虚拟系统中相对主机系统的运行效率。另一种是使用igt工具集中的intel_gpu_top工具,它通过对硬件引擎的环形囊(Ring Buffer)中指令内容的饱和程度,来判断GPU硬件的忙碌程度。intel_gpu_top的实现非常贴近硬件本身,属于近距离观察硬件,比性能软件要深入得多。如果每次采样的结果,都发现硬件的环形囊中存在尚未完成的指令,表明显卡在百分百毫不懈怠地工作。

gpu_top的所有信息来自硬件寄存器信息,只能反应物理GPU的整体性能,对于虚拟GPU它是无能为力的。GVT在不就的将来,还会加入QoS调度机制,不同的虚拟GPU示例所获得的调度机会不同。所以,如何采用一种有效的方法,衡量虚拟GPU的性能,是一个值得思考的有价值的问题。 继续阅读

124 total views, 1 views today

随笔-放慢心态1

按照现在的工作状态,实在无法保证之前的技术博客按计划进行。在罪恶感的驱使下,我拿了自己无聊时写的随笔,用来充数。看看一个仍旧奋战在一线的程序员,如何在万恶的房价经济社会中,如何苦苦挣扎。

连续两周出差,身体严重透支。正好有一个小时的时间,在等一位朋友过来。用来整理技术文章是不够,正好把这一小段时间的感想记录下来。

人生过了三十岁,时间的齿轮好像突然加快,仿佛总是处在一个“时间不够”的状态。要学习新的东西、要照顾家庭、各种朋友应酬…忙来忙去,最后都忘记了自己为了什么在忙碌。

龙应台有本书《孩子你慢慢来》,我曾经在出差途中看完。有段话,这么写的,对比得很有意境:“淡水的街头,阳光斜照着窄巷里这间零乱的花铺。 回教徒和犹太人在彼此屠杀,衣索匹亚的老弱妇孺在一个接一个地饿死,纽约华尔街的证券市场挤满了表情紧张的人——我,坐在斜阳浅照的石阶上,愿意等上一辈子的时间,让这个孩子从从容容地把那个蝴蝶结扎好,用他五岁的手指。”

我很喜欢这段话。生活从来就不美好,世界残酷而真实,美好只存在于我们的内心,那些你所珍惜的事物,导引了我们生活的方向。

大学的第一年,元旦第一天,我一个人坐在三工教学楼的某个教室里面,努力准备马上要考试的科目。第一场雪就在那个时候下起来了,我看着窗外,就这么呆呆的看着雪坐了一个上午。

那时的自己,仿佛青春永远都会在,未来的日子总感觉非常遥远。除了不时会冒出来的考试,踢球、泡图书馆、看漫画,无聊时可以花两个礼拜画一张图,从容天真。

离开学校后,画风变了。如果每个人的生活都是一场电影,那么,在离开学校的这十几年,每一帧都充满了急躁,对未来的恐惧。 继续阅读

169 total views, 1 views today

Foxdisk04-启动原理1

我不记得是哪个小品了,赵本山用他的标准铁岭普通话说:“我不想知道它怎么来的,我只想知道它是怎么没的。”

对编程而言,“怎么来的”实际上非常重要,不能不了解。Foxdisk的启动过程,在“如何安装1”中已经有了说明,本篇会尽量的把相关的背景知识介绍清楚。

有几个关键词:BBS、Legacy BIOS、UEFI、MBR。

BBS

英特尔、Phoenix和康柏公司在1996年联合发布了BIOS引导规约(BIOS Boot Specification),简称BBS(图2)。尽管十几年已经过去了,但是这个规约中的大多数内容至今仍被使用着。本文中使用的很多术语和数据结构都来自这个规约。

Foxdisk04-BBS spec

 图1 BIOS Boot Spec

BBS将引导设备划分为以下三种类型: 继续阅读

108 total views, 1 views today

Foxdisk03-如何安装2

整个Foxdisk3.01的代码,是将安装程序和主程序混在一起编译的。安装程序负责将代码拷贝到指定的硬盘区域,包括MBR代码、Foxdisk的启动代码、Foxdisk的资源、Foxdisk的code段和数据段。在“如何安装1”中叙述的foxdisk在硬盘中的映像,都是由它来实现的。

混编的好处是,安装程序能够很容易的定位主程序各种段(code、data、stack等等)的位置,方便安装。另外,很多函数可以共用。坏处是,安装程序也要占据不少的空间。我之前为了方便C和汇编混合,设定了编译模式为small,也即Code段必须在64K内,Stack和Data段加起来在64K之内。我在设计初期没有考虑好,代码写到后半段就感到很痛苦—许多想实现的功能因为代码的限制,没法去实现。

现在的编译器早就取消了这样的限制,以技术而言,BorlandC++3.1已经是石器时代的产品。以我现在常用的Vs2015,从来不用去考虑类似这样的问题,可以专注在程序本身的实现。计算机软件的发展非常快,一不小心我也变成了老古董了。

回到正题。与安装相关的文件有Setup.c、Setup.h、iSetup.c和iSetup.h,与主程序共用了磁盘访问、图像显示等函数。外设的访问,在后面专门写几个章节进行介绍,用汇编去访问外设,我估计现在除了开发驱动或者OS的程序员,很少会有人去关注它们了。

从Setup.c的main()函数开始跟踪,了解安装过程。

main函数做了两件事情: 卸载和软件安装。卸载的过程故意设计得复杂,通过判断命令行以及热键,确定用户需要完全卸载,然后再将相应的扇区覆盖。这几天我重读代码,觉得这里的设计很有问题,有可能导致卸载后无法进入操作系统了。

软件安装通过两个函数实现,firstSetup()和updateSetup()。前一个函数是首次安装,后一个是针对已经安装的软件进行参数更改或者代码升级。main()最后的汇编代码:

asm mov ax,3

asm int 0×10

其作用为回到文本模式。程序是在DOS环境下,并使用图形模式安装的,如果没有回到文本模式,DOS的命令行无法执行。

通篇代码中,有大量嵌入汇编的地方。这种写法不是很好,程序可读性比较差,我主要是习惯了汇编来实现一些小功能,不自觉的就用上了。后续出现内嵌汇编的地方,都会给出解释。

firSetup()中,将安装主程序的步骤分为了四个,代码中给出了很详细的说明,很容易读懂。此函数中所调用的图形函数和磁盘访问函数,其功能都比较单一,通过函数说明可以了解其作用。

我尽量不去调用C的库函数,以防止代码量的增加。因此,很多经典的函数,比如memset、memcpy等,只能重新自己实现。另外一个原因,Foxdisk的主程序中,是没有操作系统的,那些库函数也没法运行。我参考的代码来自于linux2.6,不愧是千锤百炼的代码,非常精简高效。

firSetup()中频繁使用的汇编代码:

asm xor ax,ax

asm int 0×16

这段代码的功能是等待按键,类似于C语言中的getchar()或者pause()。

updateSetup()的实现代码在iSetup.c中,其实现方式类似于firSetup(),就不一一解释了。

这两个函数都打开了时钟中断,实现一些需要定时的功能。篇幅所限,不再详细说明,在后续章节中针对时钟中断做一个详细说明。

128 total views, no views today

Foxdisk02-如何安装1

Foxdisk是基于BIOS中断或者直接访问硬件的,在设计的时候,第一个需要考虑的问题就是软件如何运行。这个问题很有趣,也是我在早期开发一个小的OS时试图搞清楚的最初的问题。

作为介于BIOS和操作系统间的一个小程序,我考虑了两种让Foxdisk运行的方法。其一是依靠硬件,将Foxdisk的引导代码放在PCI ROM或者以Option ROM的形式直接嵌入到BIOS中;另外一种是类似GRUB的方式,修改硬盘的MBR,实现Foxdisk的引导。我们首先从PC的启动过程谈起。

1)     PC启动的过程

Foxdisk02-PC_boot

图1 计算机启动过程

这是我理解的计算机的启动过程,显示了计算机从开机到进入操作系统的工作顺序。在上述的几个阶段,都可以抢得控制权,实现我们自己的代码。分别为:

阶段①:Call Rom,此阶段Option ROM可以抢得计算机的控制权。

阶段②:int19h,Option ROM软件可通过修改int 19h抢得控制权。另外,所有通过模拟可引导设备的Option ROM以使得BIOS能够引导其软件的方法均归于此阶段。

阶段③:LoadMBR,通过直接修改硬盘上的MBR区域抢得控制权。

阶段④:Load OS,在操作系统引导的时候抢得控制权。

阶段⑤:在操作系统层面安装软件。

阶段①~④均称为底层阶段,软件一般直接与计算机硬件打交道,或者通过BIOS中断访问硬件。阶段⑤称为上层阶段,软件借助于操作系统提供的各种API工作。

关于Option ROM的介绍,可以参考文档《BIOS Boot Specification》version 1.01。这是发布于1996年的文档,由intel、Phoenix和Compaq联合制定的规范。多年来,BIOS的启动过程也没有太大的变化,直到UEFI的出现。

具体的内容我不在博客中介绍,文档中介绍得很清楚。只要记住两点即可:第一,BIOS允许外设有自己的代码,用来实现一些特殊的功能,比如网卡的Option ROM、PCI设备的Option ROM;第二,只要依据一定的规范来写代码,BIOS会将控制权转移给Option ROM,这时整个计算机的控制权都在手中,理论上做什么都可以。

继续阅读

200 total views, no views today

Foxdisk01-缘起

Foxdisk01-bootpic

“没有任何一个题目是彻底完成了的。总还会有些是哪个可做;在经过充分的研究和洞察以后,我们可以将任何解题方法加以改进;而且无论如何,我们总可以深化我们对答案的理解。”

–《怎样解题:数学思维的新方法》

用一段话来总结我自己的这个小项目,我以为上面的这段话很精准。从2006年1.00版开始,到2008年的冬天完成3.01版,直到现在,我也不觉得这个项目完成了。只是因为各种原因,没有动力再去更新它了,曾经写在计划中的4.0版,列出了许多我很有兴趣的功能,不大可能再去实现了。

继续阅读

405 total views, 1 views today

GVT对显示引擎的虚拟(2)

引用注明>> 【作者:张佩】【原文:http://www.yiiyee.cn/Blog/

  • 1. GVT对显示中断的模拟
ISR

中断能打断普通线程的执行

显示引擎定义的中断大部分都是通用型的,不同设备厂商开发的不同代产品在工作的时候,都会不断产生这些中断。比如同步中断(v-sync和h-sync)、vblank中断、扫描中断,这些中断和终端显示器对帧囊(FrameBuffer)的处理相关,在数据处理过程中不断地实时产生;以及插拔检测(hot plug detection)中断,当显示器插入或拔出Port的时候产生。显示引擎也可能会定义一些私有类型的中断,因不同的显卡设备而异,比如一些错误检测中断,其实是硬件和软件驱动之间的一种简单的通信机制。

GVT虚拟的显示设备只实现了最基本的功能,所以模拟通用型中断就足够了。实际上,GVT现在的代码只模拟了vblank和flip done两种中断,发现已经能够满足系统驱动和大部分应用软件的需求了。当然这是不够的,已经发现了一些应用软件,依赖于线扫描中断和垂直同步中断,不久的将来,GVT会陆续加入对它们的支持。理想的情况是GVT把所有的通用型显示中断都模拟好,我们不能假设形形色色的应用软件永远不会使用某种通用型中断。 继续阅读

271 total views, 1 views today

GVT对显示引擎的虚拟(1)

引用注明>> 【作者:张佩】【原文:http://www.yiiyee.cn/Blog/

server-virtualization

这是一幅描绘了平台虚拟化的示意图

GVT是Intel针对集成显卡(IGD)设备实现的虚拟化方案,最近已经被成功地Upstream到了Linux内核4.10中了。所以用户只要拥有一份最新的Linux内核代码或镜像文件,就可以尝试这个很酷的显卡虚拟化功能。但GVT只是一个核心模块,剥离了和具体的系统虚拟化方案的耦合性,所以要想通过GVT来虚拟化你的显卡,还必须结合特定虚拟化平台下的适配模块。GVT本身是平台无关的,它通过一套公共的接口来抽象各种虚拟化平台的功能。

KVMGT是一起被Upstream的另一个模块,它就是在KVM(Kernel Virtual Machine)平台下GVT的适配模块。虚拟软件比如QEMU在KVM平台上,可以通过KVMGT暴露的用户层接口,来创建和维护GVT的虚拟GPU实例。将来,GVT在XEN和其它虚拟化平台下的适配模块,也将会被Upstream到Linux内核中去,不过这需要一些时间和持续的努力。 继续阅读

261 total views, no views today

Foxdisk00-源代码编译

为了便于之后博文的行文方便,我把代码放在了下载区:Foxdisk301 (86)

编译器使用的是Borland C++3.1,C编译器和汇编编译器都在其中。代码中包含三个汇编文件:Loaser.asm、iMath.asm、iTimeInt.asm,必须用Tasm编译。微软的masm语法要求稍微有些不同,因此foxdisk3.01的代码没有办法直接用微软早期的DOS下编译器编译。

编译步骤很简单:

1)      安装BorlandC++3.1;

2)      进入代码文件主目录,设置Path目录;(参考我的bcccmd.bat)

3)      etrhz.exe hztable.h Global.c Setup.c iSetup.c;

4)      ehz24.exe /k hzk24k.h _HZ24STR.c;

5)      运行make;

上述步骤执行后,会自动生成foxdisk.exe。在dos下安装的时候,需要调用资源文件ifox.bmp,包含在\Rleease文件夹中。

继续阅读

427 total views, no views today