Hacker News new | ask | show | jobs
by haberman 4925 days ago
> I don't think the fundamental problem with them — performance is horrible — had been made obvious yet.

On the contrary, the idea that performance of microkernels is "horrible" is the current received wisdom, believed by the majority of programmers without critical examination, and based on very performance-poor early microkernel designs like Mach.

The truth is that modern microkernel designs like L4 can perform IPC over 20 times faster than Mach. Another important advance for microkernels are tagged TLBs which can alleviate the TLB misses that are usually incurred on every context switch.

Someday, hopefully not too far in the future, someone is going to write a modern, practical, and free microkernel-based OS that implements all of POSIX with performance the rivals Linux, but that offers a level of isolation and modularity that Linux could never offer. When that happens, a lot of people are going to scratch their heads and wonder why they believed the people who told them that microkernels are "fundamentally" slow.

I had hoped that HelenOS would become this (http://www.helenos.org/), but its lowest-layer ipc abstraction is async-based, which I think is a mistake. One of L4's innovations was to use sync IPC, which offers the highest possible performance and gets the kernel out of the business of queueing. You can always build async ipc on top of sync without loss of performance; this puts the queues in user-space which is where they belong (they're easier to account for this way).

I asked the HelenOS people why they decided to go this way, and this is their response (one of their points was "the L4's focus on performance is not that important these days", which I disagree with). http://www.mail-archive.com/helenos-devel@lists.modry.cz/msg...

4 comments

What about minix 3? It implements all of POSIX, and it's a true microkernel. The kernel process is apparently only 4-5K LOC which I have been meaning to take a look through.

Their papers have pretty detailed performance measurements. I recall that they pass fixed-length messages between processes for efficiency (to avoid buffering). And they said it takes approximately 500ns to send a message on a 2.2GHz Athlon, which is in the neighborhood of a malloc().

I don't know how the overall performance is. Minix 3 appears to be targeted at lower end devices, e.g. they mentioned OLPC. I don't think they have things that you would want for servers, like multicore support. I don't think anyone uses it for those types of applications. But it does implement POSIX and it is a microkernel. And from what I gather the codebase is relatively modern -- they said it is related to Minix 2 in name only.

http://www.minix3.org/documentation/index.html

Microkernels could use some hardware optimizations... And most of those optimizations are good for virtual machines too, so they'll get done.

In due time, message passing kernels will get so much faster than interruption based ones that we'll ask ourselves why we used monolitical kernels all this time. (And somebody will have to explain that microkernels used to be slow, and this person will be met with skepticism.)

That said, the computers we had at the 80's and 90's were completely unfit for microkernels. Mach was about the best you could have by then.

(But all that discussion about microkernels is an irrelevant sideline. Linux got adopted because it was there, if it weren't we'd probably use some version of BSD instead.)

But why POSIX? There's only so much lipstick any one pig can take.
Because it gets you an immense amount of existing tools that you won't have to reimplement. You can get shells, compilers, and numerous utilities (eg cp, cat, tail, tar, zip, awk). Look at the list of what BusyBox includes to get an idea of the kind of functionality any system would need to get started. http://www.busybox.net/downloads/BusyBox.html

If you provide terminal emulation then you also get editors. If you implement ptrace then you get a debugger. If you provide networking then apps can display remotely (X).

Even if you are developing something unique for your operating system, using POSIX in that lets you perform some of the development and testing on other systems that already have working toolchains.

In short having POSIX saves a huge amount of time and effort. That doesn't preclude you from having other APIs around too. Don't underestimate the importance of having a functioning system while you replace or augment it with parts that are your unique value add.

Sure, but keep in mind that my ideal would also involve discarding most what a POSIX compatibility layer would get you. Why cleanroom a nifty kernel and then turn it into something that's almost exactly like what already exists? If you want Unix, you know where to find it, as the wag said.
The kernel doesn't have to support POSIX. You can do the emulation in user space. The only tricky part of POSIX is fork, but chances are you won't need that for compilers etc, just exec.

In any event don't confuse the journey (some POSIX compatibility in order to advantage of existing toolchains while building your new OS) for the destination (clean, elegant, new API, world changing, nifty) OS.

And if you are going to have command line tools in your OS, they will need an API and you may as well pick a useful subset of POSIX.

So at some point, you can just put the whole FOSS environment (Firefox, Gnome, Gimp, LibreOffice, etc) on top of your kernel. Porting all those programs is much more work than writing a POSIX compatibility layer.
Well, if you want all that dross, then yes, I suppose. But the hosting user software niche is well filled by various Unix derivatives already, no?
well, if you want server-type apps you will have to port them too... most run on posix.
For compatibility (see my other comment). I'm certainly not arguing that POSIX should be the "native" or only API.
> Someday, hopefully not too far in the future, someone is going to write a modern, practical, and free microkernel-based OS that implements all of POSIX with performance the rivals Linux, but that offers a level of isolation and modularity that Linux could never offer.

Why, when we already have VMs like Xen which are modern, practical, free, host guest OSes that run at full speed to provide whatever API the applications want, and provide a level of isolation and modularity microkernels never could?

I think that's a fair question, though I disagree that microkernels are somehow inherently less modular and isolated than hypervisors.

I should say, first of all, that when I said "that implements all of POSIX" I didn't mean that POSIX should be its native or only API, but just one API that is offered for compatibility with the incredible amount of existing code that targets it. I agree with your implied argument that POSIX is by no means the be-all, end-all user-space API.

But that said, I don't think that multiple OS's running under a hypervisor is the ideal way of promoting choice and diversity of APIs. First of all, there's a lot more software involved: a hypervisor, a dom0 OS, and a guest OS, just to run anything at all. Sure it works, but there's a lot to be said for a smaller and simpler base system.

When you take the hypervisor approach, every guest OS has to implement very tedious and hardware-dependent basic functionality like booting, context-switching, paging, interrupt handling, etc. instead of being able to use an API that provides these things. This is all not to mention drivers, which is one of Linux's biggest advantages over all competitors.

I see that Xen has a paravirtualization interface that can solve some of these problems, and indeed the more that the Xen<->GuestOS interface becomes like an API/ABI and less like hardware emulation, the more Xen starts to look like a microkernel. I don't know the details of how Xen's paravirtualization interface works (and couldn't find good docs on in in a quick search) so can't comment on the specifics of it.

Maybe Xen's paravirtualization will morph into what I have in mind. One litmus test would be: do I have to statically configure the amount of RAM that each guest OS is allocated? There's no need to do this for multiple processes under a single OS, but any approach that is based on hardware emulation has to decide up front how much RAM the "hardware" has available.