Отличие первое – микроядро MINIX 3 самое микроядреное микроядро в мире. Из него вычищено все, кроме перечисленных ранее компонентов, таких, как обработчик прерываний, средства запуска и останова процессов, планировщик задач, механизм межпроцессного взаимодействия; правда, почему-то в ядро включён и один из сервисов – сервис часов. В результате все это хозяйство укладывается менее чем в 4000 строк кода – и только оно исполняется в пространстве ядра.
Второе отличие – драйверная и сервисная части, вычлененные из ядра, разделены между собой. В результате образуется знаменитая четырехслойная модель – метафора, в основании которой лежит ядро, надстраиваемое «драйверным слоем», которое, в свою очередь, перекрывается «сервисным слоем» и венчается «слоем пользовательских программ».
Кроме того – и это третье отличие, – каждый драйвер и каждый сервис представляет собой отдельный процесс в пользовательском пространстве, аналогично обычным пользовательским приложениям. В результате ни один драйвер и ни один сервис, как бы криво они не были написаны, не в состоянии обрушить всю систему – точно также, как в любом UNIX'е это (почти) никогда не могут сделать обычные пользовательские приложения. Не могут повлиять они и на соседние процессы, так как напрямую взаимодействовать они не могут, а вынуждены при необходимости обращаться к ядру.
Наконец, четвертое, и, пожалуй, главное: сервер реинкарнаций. Это процесс, выступающий родительским по отношению к процессам всех драйверов и сервисов. Которые он запускает при старте, а в дальнейшем отслеживает состояние. Если процесс какого-либо драйвера или сервиса в силу неких причин самопроизвольно «умирает», он запускает его вновь. Если один из драйверов или сервисов начинает вести себя «нехорошо», сервер реинкарнаций в состоянии убить соответствующий ему процесс и тут же запустить его заново, обеспечивая, таким образом прозрачное для пользователя самовосстановление системы при отказе почти любого драйвера устройства или системной службы.
Очевидно, что такая, достаточно сложная, схема взаимодействия драйверов и системных служб не может не привести к некоторой потере производительности по сравнению с обычными системами, где драйверы и сервисы сосуществуют в едином пространстве памяти, вне зависимости от того, пользовательском или «ядерном» (а подчас еще и вместе с ядром). То есть – неизбежно должны вызвать снижение быстродействия системы. В каких масштабах? Исследования команды Таненбаума дают ответ на этот вопрос, и к нему я еще вернусь. Но сначала сделаю маленькое отступление на тему, что такое быстродействие операционной системы вообще и с чем его едят, то есть – чем меряют.
Когда обсуждается проблема быстродействия любых ОС, первым делом обычно вспоминают о скорости загрузки. Вероятно, потому, что ее проще всего измерить: достаточно посидеть с секундомером перед несколькими машинами с разными операционками или дистрибутивами, чтобы потом уверенно утверждать о их сравнительном быстродействии.
Однако имеет ли скорость загрузки системы к быстродействию ее при реальной работе? Отнюдь. Достаточно вспомнить, что MS DOS 3.3 на IBM PC/XT грузилась быстрее, чем любой Linux на любом супер-мега-Ivy Bridge. Перефразируя слова Сергея Образцова, измерение скорости загрузки ОС, строго говоря, даже к скорости загрузки ОС никакого отношения не имеет. Потому как зависит скорость загрузки в первую очередь от количества подгружаемых модулей и стартовых сервисов. Так что измерение её на самом деле меряет радиус кривизны рук пользователя, меру его лени или, напротив, количество свободного времени, которое он способен выделить на доведение системы до ума. А в последнее время, с распространением SSD-накопителей, скорость загрузки ОС вообще измеряет толщину кошелька пользователя или степень его жадности.
Не лучше и с тестами на реальных приложениях под разными ОС. Например, со столь любимым сравнением скорости обработки запросов web-сервером под Linux и FreeBSD, на основании чего делается вывод о превосходстве одной операционки над другой. Кстати, и не помню даже, кого над кем, да это и не важно. Потому что сразу же возникает закономерный вопрос: а что меряется в этом случае? Сравнительное быстродействие ОС? Или все-таки качество реализации конкретной версии Apache или, например, MySQL под ту и другую систему?
В общем, отдав в свое (не такое уж давнее) время дань увлечению всякого рода тестированием (это занятие было бы точнее классифицировать как пузометрию или … ну, то, что в этнографической литературе называют «сравнением мужей», подробно описанному в книжке: Мир FOSS. Заметки гуманитария), я пришел к стойкому убеждению, что в большинстве случаев это либо измерение аршином с точностью до ангстрема, либо, по изящному выражению Таненбаума, сравнение яблок с апельсинами.
И тем не менее, методика тестирования, предложенная командой Таненбаума, производит впечатление. Во-первых, она (команда) поставила себе целью оценить влияние на быстродействие системы одного-единственного фактора: выноса драйверов за пределы ядра и перемещения их в пользовательское пространство. И потому тестирование быстродействия MINIX 3 проводилось… на MINIX 2. Каким образом? Очень просто: в качестве сравнительных объектов использовались каноническая MINIX 2, с одной стороны, и она же, пересобранная с удалением из ядра драйверов устройств и еще некоторыми модификациями, что фактически превратило её в MINIX 3.
Во-вторых, в качестве тестов выполнялись процедуры, скорость которых действительно зависит от ОС исключительно или очень существенно: время исполнения системных вызовов, скорость чтения из файла и записи в файл, а также чтения непосредственно из блочного устройства (винчестера). Тесты с реальными приложениями тоже проводились – но предельно простыми (в смысле – мало подверженными посторонним по отношению к ОС влияниям): пересборка образа системы и набора контрольных тестов POSIX, а также обработка текстового файла утилитами типа sed, grep.
Результаты оказались парадоксальными. Разумеется, квази-Minix 3 проиграла MINIX 2 по всем статьям. Но давайте посмотрим, где и насколько.
По чисто «ядерным» тестам вроде исполнения системных вызовов отставание первой составило 12%, по тестам на файловых операциях и запросах к базам данных – 8-9%, по тестам на реальных приложениях – 6%. Последнее на современных машинах практически равнозначно отсутствию визуальной разницы вообще.
Чего нет у рыб?
Результаты тестов, о которых я только что говорил, были опубликованы в работе «A Lightweight Method for Building Reliable Operating Systems Despite Unreliable Device Drivers» ещё в январе 2006 года. Они показали, что катастрофического провала производительности при переходе к «чистому» микроядру не наблюдается. И, следовательно, идея, положенная в основу архитектуры MINIX 3:
•
имеет право на существование, и
•
заслуживает дальнейшего развития.
Так что дело оставалось за малым: воплотить идею во что-то, реально работающее. А до этого на момент публикации результатов тестов, MINIX 3 было также далеко, как омарам – нетрадиционным способом пробраться до города Пекина.
Обычно, когда описывают особенности некоей системы, разговор начинается с того, что в ней есть. Я же нарушу традицию, и расскажу о том, чего с MINIX 3 не было. И даже не в момент её анонса, а более чем год спустя, на рубеже 2006-2007 годов, когда мне довелось познакомиться с ней воочию – в актуальной на тот момент версии 3.1.2.
По поводу возможностей, отсутствующих в MINIX 3 на момент моего с ней знакомства, хочется сделать небольшое литературное отступление.
Выдающийся русский филолог и писатель Лев Успенский (автор, в числе многого прочего, замечательной книжки «Занимательная топонимика») в своих воспоминаниях рассказывает, как в студенческие годы сдавал экзамен по какой-то биологической дисциплине. И на вопрос, вынесенный в заглавие этого раздела, ответил: «У рыб нет монокля и полного собрания сочинений Шпильгагена». А на уточняющий вопрос, знает ли он, чего ещё нет у рыб, сказал: «Знаю. Но монокля и собрания сочинений Шрильгагена у них точно нет». За что и был удостоен отличной отметки.