Санкт-Петербургский государственный университет
Опубликован: 02.03.2007 | Доступ: свободный | Студентов: 3462 / 1136 | Оценка: 4.27 / 4.03 | Длительность: 07:12:00
ISBN: 978-5-9556-0104-5
Лекция 7:

Работа с временными интервалами и организация вычислительного процесса. Технологии RTST и REAL

Организация вычислительного процесса

Обычно считается, что используемая технология программирования должна обеспечить реализацию любой структуры, выдуманной проектировщиком. Однако все известные нам попытки применения общих подходов к такой сложной задаче как ПО встроенных систем реального времени, приводили к неэффективным решениям. По нашему мнению, технология программирования должна отвечать не только на традиционный вопрос "как построить, добиться, оценить", но и "что мы хотим построить". Мы к этому выводу пришли постепенно, по мере накопления опыта выполнения промышленных заказов. Чтобы обеспечить высокое качество, мы разработали технологию, первоначально полностью ориентированную только на программное обеспечение телефонных станций, которая получила название RTST — Real-Time Software Technology [28].

При разработке RTST мы заранее зафиксировали определенные структурные решения и тем самым ограничили разнообразие вариантов организации вычислительного процесса.

Процессы

Параллельные процессы — классический способ описания поведения сложных систем: независимое управление в каждой подсистеме, локализация данных, развитые средства взаимодействия позволяют описывать системы наиболее понятным для разработчиков способом. Тем не менее, в реальных системах этот способ используется редко из-за низкой эффективности реализации. Дело в том, что в них параллельно существуют тысячи процессов, абсолютное большинство которых находится в неактивном ("подвешенном") состоянии, ожидая каких-либо событий. Традиционным механизмом реализации параллелизма такого типа является диспетчеризация через короткие промежутки времени по сигналам от таймера (системы разделения времени), однако при этом самой частой операцией становится свертка/развертка процессов, сильно увеличивающая накладные расходы системы [27].

Чтобы сделать параллельные процессы эффективными, мы воспользовались особенностью встроенных систем, состоящей в том, что обычно их процессы имеют очень короткие действия — переходы в терминах расширенной конечно-автоматной модели рекомендаций Z.100 МККТТ [29]. Мы считаем, что если процесс получил управление по какому-то входному сигналу, то он должен довести переход до конца (до следующего состояния) и только затем передать управление диспетчеру, который определит, какой из процессов, готовых к исполнению (т.е. получивших сообщения), будет работать следующим. Синхронная организация параллелизма делает возможной простую процедурную реализацию, в отличие от традиционного асинхронного подхода, при реализации которого необходимы процессы. Против синхронной реализации обычно выдвигают два аргумента.

Во-первых, часть сообщений приходит по сети от других ЭВМ или оборудования в непредсказуемое время. Для решения этой проблемы соберем все функциональные процессы в один большой процесс ОС, внутри которого будем использовать синхронную организацию взаимодействия функциональных процессов, а драйверы сети, которые осуществляют буферизацию сообщений (никакой обработки!), будем реализовывать простыми обработчиками прерываний на стеке текущего процесса. Интересно, что на одно внешнее событие обычно приходится 5-10 внутренних переключений функциональных процессов.

Во-вторых, что будет, если один из процессов все-таки имеет слишком длинный переход? Тогда можно вставить несколько промежуточных фиктивных состояний (на практике это встречается крайне редко).

Такая последовательная и непрерываемая организация переходов позволяет процессам пользоваться глобальными данными (кроме списков входных сообщений, к которым имеют доступ параллельно работающие драйверы сети) без семафоров, критических интервалов и других дорогостоящих средств монополизации ресурсов.

Данные

Традиционный подход к разработке ПО встроенных систем подразумевает создание единой базы данных (централизованной или распределенной), к которой все процессы обращаются через специальные примитивы доступа. В общем случае обращение к некоторой структуре требует ее монополизации на момент обращения, что и неэффективно (несколько обращений к функциям ОС), и ненадежно (одна из самых частых и трудно обнаруживаемых ошибок возникает, когда программист забывает захватить ресурс или, что еще хуже, захватывает, но забывает освободить после использования). Проектирование единой базы данных обычно ведется только в интересах ПО без учета соответствия данных элементам реального оборудования. Это приводит к необходимости довольно сложной генерации данных ПО на основе исходной спецификации оборудования и сильно затрудняет задачу модификации данных в процессе функционирования системы ("на ходу").

Такие особенности встроенных систем, как структурное подобие большей части данных управляемому оборудованию и определенная локализация действий вокруг каждого устройства, прямо подталкивают к использованию объектно-ориентированной парадигмы, однако ее эффективность не очевидна.

Во-первых, не вызовет ли разбиение данных на сравнительно мелкие объекты (с точностью до прибора) значительного расходования памяти? Действительно, заголовки процессов в большинстве ОС достигают 100-200 байтов, поэтому представление объектов в виде полноправных процессов ОС действительно очень накладно. Но, как мы уже видели, возможны упрощенные синхронные варианты реализации объектов – при этом длина заголовка уменьшается на порядок.

Во-вторых, не подменяем ли мы сложные операции доступа к БД не менее дорогостоящими операциями обмена сообщениями? Другими словами, хорошо, если 90% запросов осуществляется к локальным данным объекта и только ради 10% приходится посылать сообщения, а если наоборот? Разумеется, на этот вопрос нет однозначного ответа, но практический опыт показывает, что обычно удается распределить данные по объектам достаточно удачно, т.е. организовать своеобразный конвейер. Сначала управление получает один объект, который, пользуясь своими локальными данными, выполняет определенные действия и посылает сообщение следующему объекту с результатами своей работы в качестве параметра сообщения, т.е. сообщения играют не только информационную, но и управляющую роль.

Случаи, когда сообщение посылается только с целью получения данных, локализованных в другом объекте, нужно сводить к минимуму. Здесь также можно воспользоваться особенностями встроенных систем, в которых процессы чаще всего далеко не равноправны по приоритетам. Например, в телефонных станциях процессы установления/освобождения соединения критичны по времени, а процессы техобслуживания, которые по объему во много раз больше, — нет. Соответственно, при разбиении системы на объекты нужно учитывать только локализацию данных, необходимых для установления и разъединения соединений, а данные, которые требуются для техобслуживания, распределять, экономя только собственные силы.

В качестве примера рассмотрим упрощенную телефонную станцию.

Упрощенная телефонная станция

Рис. 7.1. Упрощенная телефонная станция

АЛ – Абонентская Линия;

СЛ – Соединительная Линия;

ТК – Телефонная Книга;

КП – Коммутационное Поле.

Здесь каждому абоненту соответствует объект типа АЛ, каждой линии, соединяющей данную станцию с другой, — объект типа СЛ. Объект типа ТК является справочником номеров абонентов данной телефонной станции и хранит данные, необходимые для маршрутизации. Объект типа КП соответствует реальному коммутационному полю. Драйверы играют связующую роль с внешним миром и обычно реализуются в виде ассемблерных программ, вызываемых по прерываниям.

Когда абонент поднимает трубку, соответствующий объект АЛ получает сообщение, принимает все цифры номера и посылает сообщение объекту ТК с принятым номером в качестве параметра. Заметим, что все это время АЛ работает только со своими локальными данными. ТК осуществляет поиск вызываемого абонента также только по своим локальным данным и посылает сообщение найденному объекту типа АЛ или СЛ. Вызываемый абонент или соединительная линия по своим локальным данным определяет, занят он или свободен, и если свободен, то посылает сообщение КП на подключение. КП по своим локальным данным находит свободную промлинию и т.д.