接下来我们看一下对比方法,图中左边是Biscuit,这是一个我们为了论文专门用Golang写的内核,它以大概类似的方式提供了Linux中系统调用的子集。Biscuit和Linux的系统调用有相同的参数和相同的调用方式。并且我们在内核之上运行的是相同的应用程序,这里的应用程序是NGINX,这是一个web server,这里我们将相同的应用程序分别运行在Biscuit和Linux之上,应用程序会执行相同的系统调用,并传入完全相同的参数,Biscuit和Linux都会完成涉及系统调用的相同操作。之后,我们就可以研究高级编程语言内核和Linux之间的区别,并讨论优劣势是什么。以上就是对比方法的核心。
因为Linux和Biscuit并不完全一样,它们会有一些差异,所以我们花费了大量的时间来使得这里的对比尽可能的公平。
有很多同学可能会问,这里会使用什么样的高级编程语言呢?基于以下原因,我们选用了Golang。
- 这是一个静态编译的编程语言,不像Python这里没有解释器。我们喜欢静态编译的语言的原因是编译语言性能通常更好,实际上Go编译器就非常好,所以基本上来说这是一种高性能编程语言
- 另外,Golang被设计成适合系统编程,而内核就是一种系统编程所以Golang也符合这里的场景。例如:
- Golang非常容易调用汇编代码,或者其他的外部代码
- Golang能很好的支持并发
- Golang非常的灵活
- 另一个原因是Golang带有Garbage Collector。使用高级编程语言的一个优点就是你不需要管理内存,而GC是内存管理的核心。
在我们开始写论文的时候,Rust并不十分流行,并且也不是十分成熟和稳定。但是如果你现在再做相同的事情,你或许会想要用Rust来实现。因为Rust也是为系统编程而设计,它有一个小的运行时,它能生成好的代码。不过Rust相比Golang还有一个缺点,Rust认为高性能程序不能有GC,所以Rust不带GC。实际上Rust的类型系统以一种非常聪明且有趣的方式实现,所以GC对于Rust并不是必须的。这里涉及到一个有趣的问题:通过高级编程语言实现内核时,GC的代价到底有多少?而Rust通过不使用GC而跳过了这个问题。
学生提问:如果我们这里使用Rust而不是Golang来实现高级编程语言内核,通过一定的优化有没有可能达到比C内核更高的性能?
Frans教授:因为我们没有做过这样的实验,所以我就猜一下。我觉得不会有比C内核更高的性能,但是基本在同一个范围内。因为C是如此的底层,你可以假设你在Rust做的工作,都可以在C中完成。
这里有一个问题,并且在这节课最后我们会再次回顾这个问题。我们想要使用高级编程语言内核的部分原因是为了避免一类特定的Bug,那么你可以问自己的一个问题的是,你们在实验中遇到的Bug,是否可以通过使用高级编程语言来避免?我肯定你可以回想起一些Bug,它们耗费了你很多的时间,很多精力,现在你可以问自己,如果实验中的XV6是使用某种高级编程语言实现的,你的生活会不会更轻松一些?你是否能有更多时间做一些其他的事情。让我们记住这个问题,并在这节课结束的时候再看这个问题。