Универсальная 32х разрядная учебная машина (далее УУМ-32) - это программный эмулятор-отладчик для проведения исследований и обучения в области принципов функционирования операционных систем и низкоуровневого системного программирования. В рамках проекта была проведена модернизация архитектуры учебной 24-х битной ЭВМ Бека УУМ. Имея много общего с платформой х86, УУМ-32 сделала доступным для большего круга людей освоение программирования на машинном языке. В рамках развития архитектуры вводится многоядерность, что позволит изучать и проектировать ядра многопоточных ОС, а также программировать системные и прикладные многопоточные задачи.
Еще недавно конкуренция производителей процессоров приводила к ежегодному повышению тактовой частотой в 1.5-2 раза. Однако такой подход исчерпал себя несколько лет назад, т.к. повышение тактовой частоты в нормальных условиях свыше 3.8ГГц приводит к перегреву процессора. Дальнейший прирост тактовой частоты удается получить только с применением мощных систем охлаждения с применением жидкого азота. Понятно, что использования такого оборудования в домашних или офисных условиях невозможно. Здесь нужны дешевые, компактные и надежные решения.
Выход из сложившейся ситуации был найден довольно быстро - производители начали выпускать процессоры с несколькими ядрами на одном кристалле. И как это водится, любые достижения имеют свою негативную сторону и многоядерность тут не исключение. С её приходом появились три основные проблемы. Первая - существующее программное обеспечение не поддерживает многопоточного выполнения на многих ядрах и, следовательно, не может получить выигрыш в производительности на новых компьютерах. Вторая проблема - это сложность, а зачастую и невозможность распараллеливания решаемой задачи. Отладка многопоточных приложений также существенно усложнилась. Сложность заключается в том, что потоки работают совершенно независимо и их взаимодействие опирается на встроенный в операционную систему механизм межпоточной синхронизации. И, наконец, третья проблема - это избыток вычислительной мощности вследствие простоя большинства вычислительных ядер. Все эти недостатки с избытком компенсируются большим плюсом многоядерности - даже настольные компьютеры теперь могут выполнять несколько ресурсоемких задач без увеличения времени отклика операционной системы. А хорошо распараллеливаемые задачи, теперь выполняются в разы быстрее.
С появлением выше обозначенных проблем сообщество производителей программного обеспечения начало их успешно решать и обращать некоторые недостатки в коммерческую прибыль. Так, например, были выпущены новые версии программных пакетов с поддержкой многоядерности, что обеспечило существенное повышение скорости их работы. У пользователей появился выбор: либо использовать старые версии программ и работать с обычной скоростью, либо платить деньги за новые версии и получать повышение производительности.
Проблема отладки многопоточных приложений решена частично. Для таких целей были выпущены специальные пакеты разработки, например Intel parallel studio, и специальные стандарты общения между процессами, например MPI - message passing protocol. Но несмотря на это, отладка многопоточных приложений до сих пор отличается сложностью и по большей части является нетривиальной задачей.
Избыток производительности решается путем применения программно-аппаратной виртуализации. С приходом виртуализации стало возможно запускать на одной физической машине несколько конфликтующих друг с другом приложений. Это достигается путем запуска отдельных виртуальных машин с установленными на них операционными системами. Таким образом можно сократить число физических серверов, ведь теперь на одном таком сервере может размещаться несколько совершенно разных платформ.
Так как 32х разрядная универсальная учебная машина (УУМ-32) предназначена для обучения студентов современным технологиям, возникла потребность расширить архитектуру введением многоядерности. При таком подходе можно будет знакомить слушателей с основами программирования многопоточных приложений на низком уровне. На рисунке 1 представлена расширенная архитектура УУМ-32 с двумя ядрами. Причем количество ядер принципиальной роли не играет, их количество можно увеличивать практически неограниченно. Теоретической границей числа ядер служит 232, так как в командах управления ядрами обязательным параметром является 32х битный идентификатор ядра.
Применения многоядерности на эмуляторе дает значимое преимущество перед реальными системами - полный контроль над ядрами. Процесс отладки значительно упростится, ведь можно будет исполнять программу по шагам не только на конкретном ядре, но и на нескольких сразу. Например, выполнить один шаг на одном ядре, затем переключиться в режим просмотра второго и второго ядра и выполнить пару шагов там. Так же удобно будет отлаживать многопоточные программы, один из процессов которых поставляет данные для обработки другому. Процесс-поставщик может быть запущен в режиме нормального исполнения, а процесс-обработчик в режиме пошагового исполнения.
Рис. 1. Архитектура УУМ-32
Для простого и надежного управления всеми ядрами в среде УУМ-32 было введено две новых команды и два прерывания.
Команды установки и чтения контекста ядра позволят «раздавать» куски кода на исполнение разным ядрам. Это также позволит легко реализовывать операцию, подобную ветвлению программы (fork). Ветвление дает возможность отпочковать точную копию выполняемой программы на другое ядро. Это может быть полезно, например, для хорошо распараллеливаемых задач кодирования видео. Можно отпочковывать процессы, меняя константы, записанные в регистры, и отдавать новому потоку измененный контекст.
Прерывания пробуждения и режима сна ядра приводят соответственно заданное ядро в режим исполнения команд либо в режим бездействия.
Для новой архитектуры разрабатывается и новый отладчик в виде смежных панелей нескольких дизассемблерных окон - по одному на каждое ядро, как это представлено на рисунке 2. Первое время для простоты отладки будет всего два ядра.
Рис. 2. Вид отладчика в многоядерном окружении
Для более гибкой отладки панируется реализовать функции пошагового асинхронного исполнения команд, как на каждом ядре по отдельности, так и синхронного пошагового исполнения команд на всех ядрах. Такая реализация позволит даже запускать одно из ядер в нормальном режиме исполнения команд, в то время как на другом будет идти пошаговая отладка.
Помимо «классических» точек прерывания по достижению определенного адреса или регистрового условия, как это сейчас сделано в УУМ-32, а так же в любых других более серьезных отладчиках, добавляются точки прерывании при перекрытии значений регистров PC разных ядер (в этом случае программы будут выполнять одни и те же участки кода в памяти).
Самой важной проблемой параллельного программирования является правильное разделение ресурсов, не приводящее к тупикам. Для помощи в выявлении таких ситуаций будет сделан специальный тип точек прерывания - по перекрестному чтению/записи памяти. Они будут приводить к переводу всех ядер в пошаговый режим исполнения, как только хотя бы два ядра произвели чтение или запись из одного участка кода. Такая ситуация реально может произойти только при запуске эмулятора на многоядерном компьютере. Каждое ядро представлено в виде отдельного потока (thread) процесса эмулятора, но с доступом к общей памяти. Когда работа происходит на одноядерной машине, реальной параллельности нет. Все потоки квантуются по времени и путем переключения получают ограниченное процессорное время. Когда же эмулятор запущен на компьютере, содержащем хотя бы два ядра, потоки эмулятора будут работать на разных ядрах физической машины. Даже если по каким-то причинам планировщик операционной системы запустит все потоки эмулятора на одном ядре, их можно рассредоточить по разным ядрам вручную.
Ввод новой архитектуры приближает момент создания первого опытного образца микроядра операционной системы УУМ-32. Сейчас рассматриваются дальнейшие планы по улучшению архитектуры, в частности, по реорганизации памяти путем ввода страничности и снабжения этих страниц атрибутами «данные» (участок памяти может быть использован только для хранения данных, но не исполняемой программы), «код» (участок памяти может содержать только исполняемые данные и не может быть ни прочитан, ни записан), «универсальный» (участок памяти может хранить как данные, так и исполняемый код, его так же можно читать и записывать). Помимо автора, в этой области трудятся и студенты, проходящие курсы «Операционные системы» и «Системное программное обеспечение» на кафедре МОВС МИРЭА. В рамках курсовых проектов, они создают новые версии компиляторов и линковщиков для ассемблера УУМ-32. Рассматривается так же создание высокоуровнего СИ-подобного языка программирования. Всё это делается для подготовки плацдарма к созданию учебной версии операционной системы. С появлением такой операционной системы, эмулятор станет возможно применять и в учебном процессе курса «Параллельное программирование».
Библиографический список
1. Л. Бек. Введение в системное программирование: Пер. С англ. - М. Мир, 1988. - 448с.
2. Обзор реализаций учебных виртуальных ЭВМ // http://educomp.org.ru/
3. Описание структуры учебной виртуальной ЭВМ Д. Кнута MMIX-2009
4. А. Л. Бескин, А. А. Семенов «Концепция учебной виртуальной ЭВМ в подготовке инженеров на кафедре МОВС» / 57-я научно-техническая конференция МИРЭА: Сб. тр. - М.: МИРЭА, 2008 - Ч.1 стр. 93-97
5. Сайт Intel для разработчиков http://developer.intel.com
6. Интернет университет информационных технологий. Курс параллельного программирования http://www.intuit.ru/department/se/parallprog/
7. Интернет университет информационных технологий. Курс основы операционных систем http://www.intuit.ru/department/os/osintro/
8. Внутреннее устройство Microsoft Windows: Windows Server 2003, Windows XP и Windows 2000. Пер. с англ - издательство «Русская редакция» совместно с издательством «Питер», 2008. - 992с.