那么Wine的效率(性能)究竟如何?好在Wine的代码是公开的,我们可以作些分析。当然,实验结果具有更高的权威性,但是有些事是那样地明显,以致我们可以无须列举实验结果作为证明。另一方面,分析也可以使我们更好地理解和解释观察到的现象。不过,现在这里不是引用和分析、讲解源代码的地方,笔者将另外撰文分析Wine的结构和操作,现在只是粗线条地作一些说明和讨论。
我们以写文件操作为例。在Linux上,这是通过系统调用write()完成的,但是应用软件一般是通过C库函数write()或fwrite()间接地启动系统调用write(),这大家都已经很熟悉,无需多说的了。Win32 API上与C库函数write()相对应的是WriteFile(),而Windows内核与系统调用write()相对应的是NtWriteFile()。从总体上看,这两对对应物之间还是颇为相似的,似乎可以直接用write()来实现WriteFile()。那么在Wine中是怎么实现的呢?下面是笔者整理出来的NtWriteFile()伪代码描述:
feedom.net
NtWriteFile()
{ 54ne.com
向服务进程发送一个请求并等待答复; //将Handle转换成打开文件号 网管网bitsCN.com
write(); //实际的写文件操作 中国网管联盟www、bitsCN、com
向服务进程发送一个请求并等待答复; //释放打开文件号
}
这里涉及三次系统调用(其中两次为进程间通信、一次为实际的写文件操作),以及四次进程调度/切换(每次进程间通信都需要正、反两次进程调度和切换)。而在理想的情况下,则只需要一次系统调用(实际的写文件操作),不需要进程调度和切换。写文件如此,读文件也如此,事实上所有的文件操作都如此。Wine的效率如何,由此可见一斑。这就难怪Wine的开发者那么在意别人以为它是“仿真器”了。为改进Wine的效率,有人提议把服务进程搬入系统空间、使其成为内核线程,但是那只是提高了进程切换的速度和免去了系统调用时的空间切换,却并不能改变整个操作的模式、并不能减少进程调度的次数,因而并不能从根本上解决问题。
中国网管联盟www、bitsCN、com
Wine之所以要这样做,当然自有其苦衷(读者绝对不应怀疑Wine开发人员的智商)。限于本文的篇幅,笔者在这里不作分析,而只是说明:如果是在内核中实现NtWriteFile(),那就根本不需要有这个服务进程了。
网管网bitsCN_com
不过,虽然Wine本身并不是一个很好的解决方案,它对于兼容内核却有着特殊的重要性。这是因为内核并非一个操作系统的全部,在内核外面还需要许多系统软件、特别是动态连接库的配合。离开Windows系统的大量DLL,应用软件就无法运行。这些“系统DLL”是微软作为Windows的一部分、与内核捆绑在一起销售的。其实这些系统DLL大多可以从网上下载,但是那样就会涉及版权问题。而Wine恰恰为我们开发了(并且还在继续开发)许多这样的DLL。所不同的是:几个底层的、直接进行系统调用的DLL所进行的是Linux系统调用而不是Windows系统调用,这是我们需要恢复其本来面目的。另一方面,如上所述,由于Wine不涉及内核,许多本来应该放在内核中实现的功能和机制不得不放在服务进程中,从而牺牲了效率。随着兼容内核的开发,这些功能和机制将被移入内核。但是Wine的存在为我们提供了一条渐进的开发路线,而许多有关的代码则或可借鉴、或可利用。 54com.cn
所以,随着兼容内核的开发和日益完善,对于Wine所提供的资源需要在分析的基础上区别对待: 中国网管联盟www_bitscn_com
? 有许多是我们可以直接拿过来用的,主要是大量上层的DLL。
? Wine的结构框架大体上可以利用,但是需要作较大的修正。
? 贴近系统调用界面的几个DLL,特别是底层的、直接进行系统调用的DLL,则需要加以移植改写,以恢复其Windows系统对应物的本来面目。
中国网管联盟www.bitscn.com
鉴于Wine对兼容内核的重要性,笔者将另外撰写专文介绍和分析Wine的代码。
网管网bitsCN_com
