
- •1 Задачи анализа;
- •2 Задачи синтеза;
- •3 Задачи идентификации.
- •Основные задачи теории кс
- •1. Задачи анализа;
- •2. Задачи синтеза;
- •3. Задачи идентификации.
- •2. Высокой интенсивностью взаимодействия и вытекающим отсюда требованием уменьшения времени ответа.
- •Функционирование кс
- •Основные задачи теории вычислительных систем
- •Общая характеристика методов теории вычислительных систем
- •3. Классификация вычислительных систем
- •Характеристики производительности и надежности кс
- •Характеристики надежности кс
- •1 Холодное резервирование. Работает только основной канал.
- •2 Нагруженный резерв. Включены оба канала (резервный канал занимается посторонними задачами). Время перехода на основную задачу меньше чем в холодном резерве.
- •Общая характеристика методов теории вычислительных систем
- •Характеристики производительности кс
- •1. Номинальная производительность ;
- •2. Комплексная производительность ;
- •3. Пакеты тестовых программ spec XX
- •Характеристики надежности кс
- •1 Холодное резервирование. Работает только основной канал.
- •2 Нагруженный резерв. Включены оба канала (резервный канал занимается посторонними задачами). Время перехода на основную задачу меньше чем в холодном резерве.
- •4) Указывается начальное состояние системы;
- •8) Находятся показатели качества вс на основе найденных вероятностей состояния системы.
- •Анализ надежности кс со сложной структурой
- •2.Расчет надежности кс
- •2. Для каждой вершины можно вычислить среднее количество попаданий вычислительного процесса в эту вершину по формуле
- •1. Разбить множество операторов на классы:
- •Модели вычислительных систем как систем массового обслуживания
- •1 Общие понятия и определения
- •Например m/m/1
- •2 Параметры систем массового обслуживания
- •Модели массового обслуживания вычислительных систем|
- •1. Представление вычислительной системы в виде стохастической сети
- •2. Потоки заявок
- •3. Длительность обслуживания заявок
- •Характеристики одноканальных смо
- •Многопроцессорные системы
- •5. Характеристики бесприоритетных дисциплин обслуживания
- •1) В порядке поступления (первой обслуживается заявка, поступившая раньше других);
- •2) В порядке, обратном порядку поступления заявок (первой обслуживается заявка, поступившая позже других);
- •3) Наугад, т. Е. Путем случайного выбора из очереди.
- •6. Характеристики дисциплины обслуживания с относительными приоритетами заявок
- •3.8. Характеристики дисциплин обслуживания со смешанными приоритетами
- •§ 3.9. Обслуживание заявок в групповом режиме
- •§ 3.10. Смешанный режим обслуживания заявок
- •§ 3.11. Диспетчирование на основе динамических приоритетов
- •§ 3.12. Оценка затрат на диспетчирование
- •1.Определяется интенсивность потока заявок I в смо Si из системы алгебраических уравнений
- •2.Вычисляются коэффициенты передач для каждой смо
- •3.Определяется среднее время обслуживания Ui заявки в смо Si :
- •6.Для моделирующей сети в целом характеристики п.5 определяются как
- •2.Расчет характеристик мультипроцессорной системы
- •1) Имеет доступ к общей памяти;
- •1.Средняя длина очереди заявок, ожидающих обслуживания в системе:
- •3. Среднее время пребывания заявок в системе :
- •Основные задачи теории кс
- •1. Задачи анализа;
- •2. Задачи синтеза;
- •3. Задачи идентификации.
- •1) С неограниченным временем пребывания заявок;
- •2) С относительными ограничениями на время пребывания заявок;
- •3) С абсолютными ограничениями на время пребывания заявок;
- •2.4. Контроллеры и сетевые комплексы ge Fanuc
- •Модели 311,313/323, 331
- •Коммуникационные возможности серии 90-30
- •2.4.3. Контроллеры VersaMax
- •2.4.4. Программное обеспечение
- •Общая характеристика протоколов и интерфейсов асу тп
- •2. Протоколы и интерфейсы нижнего уровня.
- •2. Основные технические характеристики контроллеров и программно-технических комплексов
- •Требования к корпоративной сети
- •2) Одновременное решение различных задач или частей одной задачи;
- •3) Конвейерная обработка информации.
- •1. Суть проблемы и основные понятия
- •1.1 Главные этапы распараллеливания задач
- •1.2 Сведения о вычислительных процессах
- •1.3 Распределенная обработка данных
- •1. Классификации архитектур параллельных вычислительных систем
- •1.1 Классификация Флинна
- •1. Процессоры
- •Память компьютерных систем
- •Простые коммутаторы
- •Простые коммутаторы с пространственным разделением
- •Составные коммутаторы
- •Коммутатор Клоза
- •Баньян-сети
- •Распределенные составные коммутаторы
- •Коммутация
- •Алгоритмы выбора маршрута
- •Граф межмодульных связей Convex Exemplar spp1000
- •Граф межмодульных связей мвс-100
- •3. Граф межмодульных связей мвс-1000
- •1. Построения коммуникационных сред на основе масштабируемого когерентного интерфейса sci
- •2. Коммуникационная среда myrinet
- •3. Коммуникационная среда Raceway
- •4. Коммуникационные среды на базе транспьютероподобных процессоров
- •1. Структура узла
- •2. Пакеты и свободные символы
- •3. Прием пакетов
- •4. Передача пакетов
- •5. Управление потоком
- •1. Структура адресного пространства
- •2. Регистры управления и состояния
- •3. Форматы пакетов
- •Когерентность кэш-памятей
- •1. Организация распределенной директории
- •2. Протокол когерентности
- •3. Алгоритм кэширования.
- •1 . Основные характеристики
- •1.2. Происхождение
- •1.3. Механизм когерентности
- •1. 4. Предназначение
- •1. 5. Структура коммуникационных сред на базе sci
- •1. 6. Физическая реализация
- •1. 7. Обозначение каналов
- •2. Реализация коммуникационной среды
- •2.1. На структурном уровне коммуникационная среда состоит из трех компонентов, как показано на рис. 2.1:
- •Масштабируемый когерентный интерфейс sci
- •Сетевая технология Myrinet
- •Коммуникационная среда Raceway
- •Коммуникационные среды на базе транспьютероподобных процессоров
- •1.Информационные модели
- •1.2. Мультипроцессоры
- •1.3. Мультикомпьютеры
- •Сравнительный анализ архитектур кс параллельного действия.
- •Архитектура вычислительных систем
- •Smp архитектура
- •Симметричные мультипроцессорные системы (smp)
- •Mpp архитектура
- •Массивно-параллельные системы (mpp)
- •Гибридная архитектура (numa)
- •Системы с неоднородным доступом к памяти (numa)
- •Pvp архитектура
- •Параллельные векторные системы (pvp)
- •1. Системы с конвейерной обработкой информации
- •1.2 Мультипроцессоры uma с много- ступенчатыми сетями
- •Мультипроцессоры numa
- •Мультипроцессор Sequent numa-q
- •Мультикомпьютеры с передачей сообщений
- •1. Общая характеристика кластерных систем.
- •2.Особенности построения кластерных систем.
- •Планирование работ в cow.
- •Без блокировки начала очереди (б); заполнение прямоугольника «процессоры-время» (в). Серым цветом показаны свободные процессоры
- •Общие сведения
- •Общие сведения
- •Логическая структура кластера
- •Логические функции физического узла.
- •Устройства памяти
- •Программное обеспечение
- •Элементы кластерных систем
- •1.1. Характеристики процессоров
- •Рассмотрим в начале процессор amd Opteron/Athlon 64.
- •Примеры промышленых разработок
- •Кластерные решения компании ibm
- •Диаграмма большого Linux-кластера.
- •Аппаратное обеспечение
- •Вычислительные узлы, выполняющие основные вычислительные задачи, для которых спроектирована система.
- •Программное обеспечение
- •Кластерные решения компании hp
- •Кластерные решения компании sgi
- •Производительность операций с плавающей точкой
- •Производительность памяти
- •Производительность системы ввода/вывода Linux
- •Масштабируемость технических приложений
- •Системное программное обеспечение
- •Архитектура san
- •Компоненты san
- •Примеры решений на основе san
- •San начального уровня
- •San между основным и резервным центром
- •Практические рекомендации
- •Построение san
- •Заключение
- •Принципы построения кластерных архитектур.
- •Оценки производительности параллельных систем
- •1) Имеет доступ к общей памяти;
- •2) Имеет общий доступ к устройствам ввода-вывода;
- •3) Управляется общей операционной системой, которая обеспечивает требуемое взаимодействие между процессорами и выполняемыми им программами как на аппаратном, так и на программном уровне.
- •4 Вероятность того, что в момент поступления очередной заявки все n процессоров заняты обслуживанием
- •Выбор коммутационного компонента.
- •Проблема сетевой перегрузки.
- •1. Обзор современных сетевых решении для построения кластеров.
- •1000-Мега битный вариант Ethernet
- •Организация внешней памяти
- •Эффективные кластерные решения
- •Концепция кластерных систем
- •Разделение на High Avalibility и High Performance системы
- •3. Проблематика High Performance кластеров
- •Проблематика High Availability кластерных систем
- •Смешанные архитектуры
- •6.Средства реализации High Performance кластеров
- •7.Средства распараллеливания
- •8.Средства реализации High Availability кластеров
- •9.Примеры проверенных решений
- •Архитектура san
- •Компоненты san
- •Примеры решений на основе san
- •San начального уровня
- •San между основным и резервным центром
- •Практические рекомендации
- •Построение san
- •Заключение
- •Symmetrix десять лет спустя
- •Матричная архитектура
- •Средства защиты данных
- •Ревизионизм и фон-неймановская архитектура
- •Литература
- •Связное программное обеспечение для мультикомпьютеров
- •1. Синхронная передача сообщений.
- •2. Буферная передача сообщений.
- •Планирование работ в cow
- •Средства распараллеливания
- •7.Средства распараллеливания
- •2. Кластерн ый вычислительн ый комплекс на основе интерфейса передачи сообщений
- •2.2 Программная реализация интерфейса передачи сообщений
- •2.3 Структура каталога mpich
- •2.4 «Устройства» mpich
- •2.5 Выполнение параллельной программы
- •2.6 Особенности выполнения программ на кластерах рабочих станций
- •2.7 Тестирование кластерного комплекса
- •Параллельная виртуальная машина
- •3 Кластерн ый вычислительн ый комплекс на основе пАраллельной виртуальной машины
- •3.1 Параллельная виртуальная машина
- •3.1.1 Общая характеристика
- •3.1.2 Гетерогенные вычислительные системы
- •3.1.3 Архитектура параллельной виртуальной машины
- •3.2 Настройка и запуск параллельной виртуальной машины
- •3.3 Структура каталога pvm
- •3.4 Тестирование параллельной виртуальной машины
- •На рисунке 3.2 представлена диаграмма, отображающая сравнение производительности коммуникационных библиотек mpi и pvm.
- •3.5 Сходства и различия pvm и mpi
- •4 . Кластерн ый вычислительн ый комплекса на основе программного пакета openMosix
- •4.1 Роль openMosix
- •4.2 Компоненты openMosix
- •4.2.1 Миграция процессов
- •4.2.2 Файловая система openMosix (oMfs)
- •4.3 Планирование кластера
- •4.4 Простая конфигурация
- •4.4.1 Синтаксис файла /etc/openmosix.Map
- •4.4.2 Автообнаружение
- •4. 5. Пользовательские утилиты администрирования openMosix
- •4. 6. Графические средства администрирования openMosix
- •4. 6.1 Использование openMosixView
- •4. 6.1.2 Окно конфигурации. Это окно появится после нажатия кнопки “cluster-node”.
- •4. 6.1.3 Окно advanced-execution. Если нужно запустить задания в кластере, то диалог "advanced execution" может сильно упростить эту задачу.
- •4.6.1.4 Командная строка. Можно указать дополнительные аргументы командной строки в поле ввода вверху окна. Аргументы приведены в таблице 9.2.
- •4. 6.2.2 Окно migrator. Этот диалог появляется, если кликнуть на каком-либо процессе из окна списка процессов.
- •4. 6.2.3 Управление удалёнными процессами. Этот диалог появляется при нажатии кнопки “manage procs from remote”
- •4.5.3 Использование openMosixcollector
- •4. 6.4 Использование openMosixanalyzer
- •4. 6.4. 1 Окно load-overview. Здесь отображается хронология нагрузки openMosix.
- •4. 6.4. 2 Статистическая информация об узле
- •4.5.4.3 Окно memory-overview. Здесь представляется обзор использования памяти (Memory-overview) в openMosixanalyzer.
- •4. 6.4.4 Окно openMosixhistory
- •4. 6.5 Использование openMosixmigmon
- •4.6 Список условных сокращений
- •Перечень ссылок
- •Общие сведения
- •2. Создание Windows-кластера
- •Суперкомпьютерная Программа "скиф"
- •Описание технических решений
- •Направления работ
- •Основные результаты
- •Кластер мгиу
- •Содержание
- •Понятие о кластере
- •Аппаратное обеспечение
- •Пропускная способность и латентность
- •1. Определение распределенной системы
- •2.1. Соединение пользователей с ресурсами
- •2.2. Прозрачность
- •Прозрачность в распределенных системах
- •2.3. Открытость
- •2.4. Масштабируемость
- •3.1. Мультипроцессоры
- •3.2. Гомогенные мультикомпьютерные системы
- •3.3. Гетерогенные мультикомпьютерные системы
- •4. Концепции программных решений рс
- •4.1. Распределенные операционные системы
- •4.2. Сетевые операционные системы
- •4.3. Программное обеспечение промежуточного уровня
- •5. Модель клиент-сервер рс
- •5.1. Клиенты и серверы
- •5.2. Разделение приложений по уровням
- •5.3. Варианты архитектуры клиент-сервер
- •Формы метакомпьютера
- •Настольный суперкомпьютер.
- •2. Интеллектуальный инструментальный комплекс.
- •Сетевой суперкомпьютер.
- •Проблемы создания метакомпьютера
- •Сегодняшняя архитектура метакомпьютерной среды
- •Взаимосвязь метакомпьютинга с общими проблемами развития системного по
- •5. Модель клиент-сервер рс
- •5.1. Клиенты и серверы
- •5.2. Разделение приложений по уровням
- •5.3. Варианты архитектуры клиент-сервер
- •Symmetrix десять лет спустя
- •Матричная архитектура
- •Средства защиты данных
- •Ревизионизм и фон-неймановская архитектура
- •Однородные вычислительные среды
- •Однокристальный ассоциативный процессор сам2000
- •Модели нейронных сетей
- •Модели инс
- •Оптимизационные системы.
- •Неуправляемые системы распознавания образов.
- •Системы feed forward.
- •Элементы нейрологики с позиции аппаратной реализации
- •Реализация нейронных сетей
- •Программные нейрокомпьютеры
- •Программно-аппаратные нейрокомпьютеры
- •Практическое использование инс
4.1. Распределенные операционные системы
Существует два типа распределенных операционных систем. Мультипроцессорная операционная система (multiprocessor operating system) управляет ресурсами мультипроцессора. Мультикомпьютерная операционная система (multicomputer operating system) разрабатывается для гомогенных мультикомпьютеров.
Функциональность распределенных операционных систем в основном не отличается от функциональности традиционных операционных систем, предназначенных для компьютеров с одним процессором за исключением того, что она поддерживает функционирование нескольких процессоров. Поэтому давайте кратко обсудим операционные системы, предназначенные для обыкновенных компьютеров с одним процессором.
Операционные системы для однопроцессорных компьютеров
Операционные системы традиционно строились для управления компьютерами с одним процессором. Основной задачей этих систем была организация легкого доступа пользователей и приложений к разделяемым устройствам, таким как процессор, память, диски и периферийные устройства. Говоря о разделении ресурсов, мы имеем в виду возможность использования одного и того же аппаратного обеспечения различными приложениями изолированно друг от друга. Для приложения это выглядит так, словно эти ресурсы находятся в его полном распоряжении, при этом в одной системе может выполняться одновременно несколько приложений, каждое со своим собственным набором ресурсов. В этом смысле говорят, что операционная система реализует виртуальную машину (virtual machine), предоставляя приложениям средства мультизадачности.
Важным аспектом совместного использования ресурсов в такой виртуальной машине является то, что приложения отделены друг от друга. Так, невозможна ситуация, когда при одновременном исполнении двух приложений, А и В, приложение А может изменить данные приложения В, просто работая с той частью общей памяти, где эти данные хранятся.
Также требуется гарантировать, что приложения смогут использовать предоставленные им средства только так, как предписано операционной системой. Например, приложениям обычно запрещено копировать сообщения прямо в сетевой интерфейс. Взамен операционная система предоставляет первичные операции связи, которые можно использовать для пересылки сообщений между приложениями на различных машинах.
Следовательно, операционная система должна полностью контролировать использование и распределение аппаратных ресурсов. Поэтому большинство процессоров поддерживают как минимум два режима работы.
В режиме ядра (kernel mode) выполняются все разрешенные инструкции, а в ходе выполнения доступна вся имеющаяся память и любые регистры.
Напротив, в пользовательском режиме (user mode) доступ к регистрам и памяти ограничен. Так, приложению не будет позволено работать с памятью за пределами набора адресов, установленного для него операционной системой, или обращаться напрямую к регистрам устройств. На время выполнения кода операционной системы процессор переключается в режим ядра. Однако единственный способ перейти из пользовательского режима в режим ядра — это сделать системный вызов, реализуемый через операционную систему. Поскольку системные вызовы — это лишь базовые службы, предоставляемые операционной системой, и поскольку ограничение доступа к памяти и регистрам нередко реализуется аппаратно, операционная система в состоянии полностью их контролировать.
Существование двух режимов работы привело к такой организации операционных систем, при которой практически весь их код выполняется в режиме ядра. Результатом часто становятся гигантские монолитные программы, работающие в едином адресном пространстве. Оборотная сторона такого подхода состоит в том, что перенастроить систему часто бывает нелегко. Другими словами, заменить или адаптировать компоненты операционной системы без полной перезагрузки, а возможно и полной перекомпиляции и новой установки очень трудно. С точки зрения открытости, проектирования программ, надежности или легкости обслуживания монолитные операционные системы — это не самая лучшая из идей.
Более удобен вариант с организацией операционной системы в виде двух частей.
Одна часть содержит набор модулей для управления аппаратным обеспечением, которые прекрасно могут выполняться в пользовательском режиме. Например, управление памятью состоит в основном из отслеживания, какие блоки памяти выделены под процессы, а какие свободны. Единственный момент, когда мы нуждаемся в работе в режиме ядра, — это установка регистров блока управления памятью.
Вторая часть операционной системы содержит небольшое микроядро (microkernel), содержащее исключительно код, который выполняется в режиме ядра. На практике микроядро должно содержать только код для установки регистров устройств, переключения процессора с процесса на процесс, работы с блоком управления памятью и перехвата аппаратных прерываний. Кроме того, в нем обычно содержится код, преобразующий вызовы соответствующих модулей пользовательского уровня операционной системы в системные вызовы и возвращающий результаты. Такой подход приводит к организации, показанной на рис. 1.8.
Использование микроядра дает нам разнообразные преимущества. Наиболее важное из них состоит в гибкости: поскольку большая часть операционной системы исполняется в пользовательском режиме, относительно несложно заменить один из модулей без повторной компиляции или повторной установки всей системы.
Другой серьезный плюс заключается в том, что модули пользовательского уровня могут в принципе размещаться на разных машинах. Так, мы можем установить модуль управления файлами не на той машине, на которой он управляет службой каталогов. Другими словами, подход с использованием микроядра отлично подходит для переноса однопроцессорных операционных систем на распределенные компьютеры.
У микроядер имеется два существенных недостатка.
Во-первых, они работают иначе, чем существующие операционные системы, а попытки поменять сложившееся «статус-кво» всегда встречают активное сопротивление («если эта операционная система подходила для моего деда — она подойдет и для меня»).
Во-вторых, микроядро требует дополнительного обмена, что слегка снижает производительность. Однако, зная как быстры современные процессоры, снижение производительности в 20 % вряд ли можно считать фатальным.
Мультипроцессорные операционные системы
Важным, но часто не слишком очевидным расширением однопроцессорных операционных систем является возможность поддержки нескольких процессоров, имеющих доступ к совместно используемой памяти. Концептуально это расширение несложно. Все структуры данных, необходимые операционной системе для поддержки аппаратуры, включая поддержку нескольких процессоров, размещаются в памяти. Основная разница заключается в том, что теперь эти данные доступны нескольким процессорам и должны быть защищены от параллельного доступа для обеспечения их целостности.
Однако многие операционные системы, особенно предназначенные для персональных компьютеров и рабочих станций, не могут с легкостью поддерживать несколько процессоров. Основная причина такого поведения состоит в том, что они были разработаны как монолитные программы, которые могут выполняться только в одном потоке управления.
Адаптация таких операционных систем под мультипроцессорные означает повторное проектирование и новую реализацию всего ядра. Современные операционные системы изначально разрабатываются с учетом возможности работы в мультипроцессорных системах.
Многопроцессорные операционные системы нацелены на поддержание высокой производительности конфигураций с несколькими процессорами. Основная их задача — обеспечить прозрачность числа процессоров для приложения. Сделать это достаточно легко, поскольку сообщение между различными приложениями или их частями требует тех же примитивов, что и в многозадачных однопроцессорных операционных системах. Идея состоит в том, что все сообщение происходит путем работы с данными в специальной совместно используемой области данных, и все что нам нужно — это защитить данные от одновременного доступа к ним. Защита осуществляется посредством примитивов синхронизации.
Два наиболее важных (и эквивалентных) примитива — это семафоры и мониторы.
Семафор (semaphore) может быть представлен в виде целого числа, поддерживающего две операции: up (увеличить) и down (уменьшить). При уменьшении сначала проверяется, превышает ли значение семафора 0. Если это так, его значение уменьшается, и выполнение процесса продолжается. Если же значение семафора нулевое, вызывающий процесс блокируется. Оператор увеличения совершает противоположное действие. Сначала он проверяет все заблокированные в настоящее время процессы, которые были неспособны, завершиться в ходе предыдущей операции уменьшения. Если таковые существуют, он разблокирует один из них и продолжает работу. В противном случае он просто увеличивает счетчик семафора. Разблокированный процесс выполняется до вызова операции уменьшения. Важным свойством операций с семафорами является то, что они атомарны (atomic), то есть в случае запуска операции уменьшения или увеличения до момента ее завершения (или до момента блокировки процесса) никакой другой процесс не может получить доступ к семафору.
Известно, что программирование с использованием семафоров для синхронизации процесса вызывает множество ошибок, кроме, разве что, случаев простой защиты разделяемых данных. Основная проблема состоит в том, что наличие семафоров приводит к неструктурированному коду. Похожая ситуация возникает при частом использовании печально известной инструкции goto. В качестве альтернативы семафорам многие современные системы, поддерживающие параллельное программирование, предоставляют библиотеки для реализации мониторов.
Формально монитор (monitor) представляет собой конструкцию языка программирования, такую же, как объект в объектно-ориентированном программировании [200]. Монитор может рассматриваться как модуль, содержащий переменные и процедуры. Доступ к переменным можно получить только путем вызова одной из процедур монитора. В этом смысле монитор очень похож на объект. Объект также имеет свои защищенные данные, доступ к которым можно получить только через методы, реализованные в этом объекте. Разница между мониторами и объектами состоит в том, что монитор разрешает выполнение процедуры только одному процессу в каждый момент времени. Другими словами, если процедура, содержащаяся в мониторе, выполняется процессом А (мы говорим, что А вошел в монитор) и процесс В также вызывает одну из процедур монитора, В будет блокирован до завершения выполнения А (то есть до тех пор, пока А не покинет монитор).
В качестве примера рассмотрим простой монитор для защиты целой переменной (листинг 1.1). Монитор содержит одну закрытую (private) переменную count, доступ к которой можно получить только через три открытых (public) процедуры — чтения текущего значения, увеличения на единицу и уменьшения. Конструкция монитора гарантирует, что любой процесс, который вызывает одну из этих процедур, получит атомарный доступ к внутренним данным монитора.
Листинг 1.1. Монитор, предохраняющий целое число от параллельного доступа
monitor Counter { private:
int count = 0; public:
int valueO { return count; }
void incr() { count = count +1:}
void decrO { count = count - 1:} }
Итак, мониторы пригодны для простой защиты совместно используемых данных. Однако для условной блокировки процесса необходимо большее. Например, предположим, нам нужно заблокировать процесс при вызове операции уменьшения, если обнаруживается, что значение count равно нулю. Для этой цели в мониторах используются условные переменные (condition variables). Это специальные переменные с двумя доступными операциями: wait (ждать) и signal (сигнализировать). Когда процесс А находится в мониторе и вызывает для условной переменной, хранящейся в мониторе, операцию wait, процесс А будет заблокирован и откажется от своего исключительного доступа к монитору. Соответственно, процесс В, ожидавший получения исключительного доступа к монитору, сможет продолжить свою работу. В определенный момент времени В может разблокировать процесс А вызовом операции signal для условной переменной, которого ожидает А. Чтобы предотвратить наличие двух активных процессов внутри монитора, мы доработаем схему так, чтобы процесс, подавший сигнал, покидал монитор. Теперь мы можем переделать наш предыдущий пример. Монитор из листинга 1.2 — это новая реализация обсуждавшегося ранее семафора.
Листинг 1.2. Монитор, предохраняющий целое число от параллельного доступа и блокирующий процесс.
monitor Counter { private:
int count = 0;
int blocked_procs = 0;
condition unblocked: public:
int valueO { return count;}
void incrO {
if (blocked_procs == 0)
count = count + 1: ., else
signal( unblocked ): }
void decrO { if (count == 0) {
blocked_procs = blocked_procs + 1;
wait( unblocked );
blocked procs = blocked procs - 1;
} else
count = count - 1; } }
Оборотная сторона мониторов состоит в том, что они являются конструкциями языка программирования. Так, Java поддерживает мониторы, просто разрешая каждому объекту предохранять себя от параллельного доступа путем использования в нем инструкции synchronized и операций wait и notify. Библиотечная поддержка мониторов обычно реализуется на базе простых семафоров, которые могут принимать только значения 0 и 1. Такие семафоры часто называются переменными -мьютексами (mutex variables), или просто мьютексами. С мьютексами ассоциируются операции lock (блокировать) и unlock (разблокировать). Захват мьютекса возможен только в том случае, если его значение равно единице, в противном случае вызывающий процесс будет блокирован. Соответственно, освобождение мьютекса означает установку его значения в 1, если нет необходимости разблокировать какой-нибудь из ожидающих процессов. Условные переменные и соответствующие им операции также поставляются в виде библиотечных процедур. Дополнительную информацию по примитивам синхронизации можно найти в [17].
Мультикомпьютерные операционные системы
Мультикомпьютерные операционные системы обладают гораздо более разнообразной структурой и значительно сложнее, чем мультипроцессорные. Эта разница проистекает из того факта, что структуры данных, необходимые для управления системными ресурсами, не должны больше отвечать условию легкости совместного использования, поскольку их не нужно помещать в физически общую память.
Единственно возможным видом связи является передача сообщений (message passing). Мультикомпьютерные операционные системы в основном организованы так, как показано на рис. 1.9.
Каждый узел имеет свое ядро, которое содержит модули для управления локальными ресурсами — памятью, локальным процессором, локальными дисками и т. д. Кроме того, каждый узел имеет отдельный модуль для межпроцессорного взаимодействия, то есть посылки сообщений на другие узлы и приема сообщений от них.
Поверх каждого локального ядра лежит уровень программного обеспечения общего назначения, реализующий операционную систему в виде виртуальной машины, поддерживающей параллельную работу над различными задачами. На деле, как мы сейчас кратко рассмотрим, этот уровень может даже предоставлять абстракцию мультипроцессорной машины. Другими словами, он предоставляет полную программную реализацию совместно используемой памяти. Дополнительные средства, обычно реализуемые на этом уровне, предназначены, например, для назначения задач процессорам, маскировки сбоев аппаратуры, обеспечения прозрачности сохранения- и общего обмена между процессами. Другими словами, эти средства абсолютно типичны для операционных систем вообще.
Мультикомпьютерные операционные системы, не предоставляющие средств для совместного использования памяти, могут предложить приложениям только средства для обмена сообщениями. К сожалению, семантика примитивов обмена сообщениями в значительной степени разная для разных систем. Понять эти различия проще, если отмечать, буферизуются сообщения или нет. Кроме того, мы нуждаемся в учете того, блокируется ли посылающий или принимающий процесс. На рис. 1.10 продемонстрирован вариант с буферизацией и блокировкой.
Существует всего два возможных места буферизации сообщений — на стороне отправителя или на стороне получателя. Это приводит к четырем возможным точкам синхронизации, то есть точкам возможной блокировки отправителя или получателя. Если буферизация происходит на стороне отправителя, это дает возможность заблокировать отправителя, только если его буфер полон, что показано точкой синхронизации S1 на рисунке. С другой стороны, процедура помещения сообщения в буфер может возвращать состояние, показывающее, что операция успешно выполнена. Это позволяет отправителю избежать блокировки по причине переполнения буфера. Если же отправитель не имеет буфера, существует три альтернативных точки блокировки отправителя: отправление сообщения (точка 52), поступление сообщения к получателю (точка S3), принятие сообщения получателем (точка S4). Отметим, что если блокировка происходит в точке S2, S3 или S4, наличие или отсутствие буфера на стороне отправителя не имеет никакого значения.
Блокировка получателя имеет смысл только в точке синхронизации S3 и может производиться, только если у получателя нет буфера или если буфер пуст. Альтернативой может быть опрос получателем наличия входящих сообщений. Однако эти действия часто ведут к пустой трате процессорного времени или слишком запоздалой реакции на пришедшее сообщение, что, в свою очередь, приводит к переполнению буфера входящими сообщениями и их потере [52].
Другой момент, важный для понимания семантики обмена сообщениями, — надежность связи. Отличительной чертой надежной связи является получение отправителем гарантии приема сообщения. На рис. 1.10 надежность связи означает, что все сообщения гарантированно достигают точки синхронизации S3. При ненадежной связи всякие гарантии отсутствуют. Если буферизация производится на стороне отправителя, о надежности связи ничего определенного сказать нельзя. Также операционная система не нуждается в гарантированно надежной связи в случае блокировки отправителя в точке 52.
С другой стороны, если операционная система блокирует отправителя до достижения сообщением точки S3 или S4, она должна иметь гарантированно надежную связь. В противном случае мы можем оказаться в ситуации, когда отправитель ждет подтверждения получения, а сообщение было потеряно при передаче. Отношение между блокировкой, буферизацией и гарантиями относительно надежности связи суммированы в табл. 1.4.
Множество аспектов проектирования мультикомпьютерных операционных систем одинаково важны для любой распределенной системы. Основная разница между мультикомпьютерными операционными системами и распределенными системами состоит в том, что в первом случае обычно подразумевается, что аппаратное обеспечение гомогенно и полностью управляемо. Множество распределенных систем, однако, строится на базе существующих операционных систем. Далее мы обсудим этот вопрос.
Системы с распределенной разделяемой памятью
Практика показывает, что программировать мультикомпьютерные системы значительно сложнее, чем мультипроцессорные. Разница объясняется тем, что связь посредством процессов, имеющих доступ к совместно используемой памяти, и простых примитивов синхронизации, таких как семафоры и мониторы, значительно проще, чем работа с одним только механизмом обмена сообщениями. Такие вопросы, как буферизация, блокировка и надежность связи, только усложняют положение.
По этой причине проводились впечатляющие исследования по вопросу эмуляции совместно используемой памяти на мультикомпьютерных системах. Их целью было создание виртуальных машин с разделяемой памятью, работающих на мультикомпьютерных системах, для которых можно было бы писать приложения, рассчитанные на модель совместно используемой памяти, даже если физически она отсутствует. Главную роль в этом играет мультикомпьютерная операционная система.
Один из распространенных подходов — задействовать виртуальную память каждого отдельного узла для поддержки общего виртуального адресного пространства. Это приводит нас к распределенной разделяемой памяти (Distributed Shared Memory, DSM) со страничной организацией.
Принцип работы этой памяти следующий. В системе с DSM адресное пространство разделено на страницы (обычно по 4 или по 8 Кбайт), распределенные по всем процессорам системы. Когда процессор адресуется к памяти, которая не является локальной, происходит внутреннее прерывание, операционная система считывает в локальную память страницу, содержащую указанный адрес, и перезапускает выполнение вызвавшей прерывание инструкции, которая теперь успешно выполняется.
Этот подход продемонстрирован на рис. 1.11, а для адресного пространства из 16 страниц и четырех процессоров. Это вполне нормальная страничная организация, если не считать того, что в качестве временного хранилища информации используется не диск, а удаленная оперативная память.
В этом примере при обращении процессора 1 к коду или данным со страницы О, 2, 5 или 9 обращение происходит локально. Ссылки на другие страницы вызывают внутреннее прерывание. Так, например, ссылка на адрес со страницы 10 вызывает внутреннее прерывание операционной системы, и она перемещает страницу 10 с машины 2 на машину 1, как показано на рис. 1.11, б.
Одно из улучшений базовой системы, часто позволяющее значительно повысить ее производительность, — это репликация страниц, которые объявляются закрытыми на запись, например, страниц, содержащих текст программы, константы «только для чтения» или другие закрытые на запись структуры.
Например, если страница 10 — это секция текста программы, ее использование процессором 1 приведет к пересылке процессору 1 ее копии, а оригинал в памяти процессора 2 будет продолжать спокойно храниться, как показано на рис. 1.11, в. В этом случае процессоры 1 и 2 оба смогут обращаться к странице 10 так часто, как им понадобится, не вызывая при этом никаких внутренних прерываний для выборки памяти.
Другая возможность — это репликация также и не закрытых на запись страниц, то есть любых страниц. Пока производится только чтение, никакой разницы между репликацией закрытых и незакрытых на запись страниц нет. Однако если реплицированная страница внезапно изменяется, необходимо предпринимать специальные действия для предотвращения появления множества несовместимых копий. Обычно все копии, кроме одной, перед проведением записи объявляются неверными.
Дополнительного увеличения производительности можно добиться путем ухода от строгого соответствия между реплицируемыми страницами. Другими словами, мы позволяем отдельной копии временно отличаться от других. Практика показывает, что этот подход действительно может помочь, но, к сожалению, может также сильно осложнить жизнь программиста, вынужденного в этом случае отслеживать возможную несовместимость. Поскольку основной причиной разработки DSM была простота программирования, ослабление соответствия не находит реального применения. Мы вернемся к проблемам соответствия в главе 6.
Другой проблемой при разработке эффективных систем DSM является вопрос о размере страниц. Мы сталкивались с подобным выбором, когда рассматривали вопрос размера страниц в однопроцессорной системе с виртуальной памятью. Так, затраты на передачу страницы по сети в первую очередь определяются затратами на подготовку к передаче, а не объемом передаваемых данных. Соответственно, большой размер страниц может снизить общее число сеансов передачи при необходимости доступа к большому количеству последовательных элементов данных. С другой стороны, если страница содержит данные двух независимых процессов, выполняющихся на разных процессорах, операционная система будет вынуждена постоянно пересылать эту страницу от одного процессора к другому, как показано на рис. 1.12. Размещение данных двух независимых процессов на одной странице называется ошибочным разделением {false sharing).
После почти 15 лет исследований распределенной памяти совместного использования разработчики DSM продолжают добиваться сочетания эффективности и легкости программирования. Для достижения высокой производительности крупномасштабных мультикомпыотерных систем программисты прибегают к пересылке сообщений, невзирая на ее высокую, по сравнению с программированием систем (виртуальной) памяти совместного использования, сложность. Это позволяет нам сделать вывод о том, что DSM не оправдывает наших ожиданий для высокопроизводительного параллельного программирования. Дополнительную информацию по DSM можно найти в книге [363].