© 2001 г.
Б. П. Кузнецов
Печатная версия опубликована в журнале "Автоматика и телемеханика", 1999, N 2.
Можно скачать текст статьи в формате html (89 кб)
Вводится понятие независимости фрагментов модулей циклических
программ и предложено оценивать условное число путей в модуле по
специальной расчетной схеме. Предложена новая оценка сложности
модулей с учетом локальной статической памяти. Предложено использовать
модель С-автомата для реализации модулей циклических программ и
способы оптимизации таких модулей по сложности и быстродействию.
1. Введение
Циклические программы используются практически в любом программном обеспечении.
При этом циклы могут быть явными и неявными. В частности неявный цикл
присутствует в обработчиках прерываний, которые фактически работают в
бесконечном цикле, чье тело инициируется прерыванием. Циклическими являются и
подпрограммы - оконные функции приложений Windows. Далее рассматриваются
программы с циклом, тело которо-го содержит функциональные модули.
Например, программа автоматического управления имеет структуру, изображенную
на рис. 1. Модули, входящие в цикл (а также модули обработки прерываний), с
одним входом и одним выходом каждый, как правило, имеют характерную особенность:
модули содержат статические переменные, которым присваивается значение в
текущем цикле, а анализ этих переменных выполняется в следующем цикле. Таким
образом, упомянутые переменные характеризуют состояние модуля на конец текущего
или начало следующего цикла программы. В дальнейшем будем рассматривать только
такие модули циклических программ и обозначать их кратко МЦП.
Рис.1. Типовая структура управляющей программы с бесконечным циклом.
МЦП имеют разнообразную структуру, сложность которой необходимо оценивать по
специальным критериям. В.В.Липаевым предложен удобный и объективный критерий
сложности программных модулей, а именно: число и суммарная длина путей в
управляющем графе модуля [1]. При этом учитываются только условные операторы и
операторы выбора. Однако этого критерия явно недостаточно для МЦП со
статической памятью, ибо при анализе МЦП необходимо помнить значения всех
статических переменных, установленные в предшествующем цикле. Помимо этого,
никаких рекомендаций по стандартизации алгоритмов и программ, кроме давно
известного структурного программирования [2] на общеупотребительных языках
программирования типа Си и Паскаль - нет. В данной статье предлагается
восполнить эти пробелы применительно к МЦП.
2. Фрагменты модулей циклических программ
Двухполюсным фрагментом, или просто фрагментом, будем считать участок программы
с одним входом и одним выходом (включая операторы циклов) в предположении, что
рассматриваемые МЦП структурированы. Простейший фрагмент включает единственный
оператор. Последовательность фрагментов также является фрагментом. МЦП в свою
очередь является фрагментом и состоит из последовательности фрагментов.
В [3] предложен метод независимых фрагментов для синтеза структуры модулей,
реализующих таблицы решений. При этом независимым считается такой фрагмент,
который можно вставить в любом месте последовательности фрагментов модуля.
Независимость местоположения такого фрагмента обусловлена тем, что анализируемые
в нем данные не формируются в указанной последовательности фрагментов, а
формируемые в независимом фрагменте данные не анализируются в данной
последовательности фрагментов. Поэтому независимые фрагменты могут выполняться
параллельно (псевдопараллельно). На рис. 2 показаны возможные варианты
реализации модуля с двумя независимыми фрагментами. В вариантах “а” и “б”
фрагменты переставлены местами без искажения существа программы; в варианте “в”
фрагменты реализуются параллельно.
Рис.2. Варианты реализации модуля с независимыми фрагментами:
а) и б) - последовательная реализация,
в) - параллельная реализация: двойная горизонтальная линия обозначает
распараллеливание программы, жирная горизонтальная черта обозначает
завершение параллельных процессов.
Зависимым фрагментом является такой, местоположение которого зависит от
местоположения другого (других) фрагмента в модуле. Будем различать сверху- и
снизу зависимые фрагменты. Сверху-зависимый фрагмент должен быть расположен
всегда ниже некоторого фрагмента, в котором формируются переменные, используемые
в данном (зависимом) фрагменте. Снизу-зависимый фрагмент должен размещаться
всегда выше фрагмента, в котором используются переменные, формируемые в данном
фрагменте. Два зависимых фрагмента, один из которых является сверху зависимым
от второго, а второй снизу зависимым от первого, будем называть взаимно
зависимыми фрагментами. Их нельзя менять местами и нельзя реализовывать
параллельно. На рис. 3 приведен пример модуля с взаимно зависимыми фрагментами.
Между взаимно зависимыми фрагментами могут находиться другие, зависимые или не
зависимые от них.
Рис.3. Модуль с зависимыми фрагментами.
Фиксированным будем называть зависимый фрагмент, местоположение которого в
модуле строго определено. Например, в модуле распознавания символа, введенного
с клавиатуры, первым должен быть снизу зависимый фрагмент непосредственно ввода
символа. Операторы “начало” и “конец” модуля есть фиксированные фрагменты.
Абсолютно независимых фрагментов не существует хотя бы потому, что в любом
модуле есть упомянутые фиксированные фрагменты начала и конца. Поэтому
независимый фрагмент, в общем случае, имеет ограниченную двумя взаимно
зависимыми фрагментами область возможного местоположения. То есть более строгое
определение независимого фрагмента звучит следующим образом: независимым
относительно двух фиксированных фрагментов будем называть такой фрагмент,
который может быть размещен в любом месте последовательности фрагментов,
ограниченной сверху и снизу указанными фиксированными фрагментами.
Так как модули программы являются ее фрагментами, то все перечисленные
определения распространяются и на них; модули могут быть зависимыми,
фиксированными и независимыми.
Математических определений зависимости и независимости фрагментов здесь не
дается, так как нас интересуют не вопросы размещения фрагментов, а влияние их
зависимости на критерии сложности МЦП.
3. Число маршрутов в модулях циклических программ
Рассмотрим влияние зависимости фрагментов на критерий сложности модулей по
Липаеву, то есть на число маршрутов в модулях. В дальнейшем под термином
“маршрут” (“путь”) будем подразумевать так называемые условные (объясняется
ниже) маршруты (пути).
Обозначим S - общее число маршрутов (путей) в модуле, а Sn - число путей в
n-ом фрагменте этого модуля.
Пусть модуль содержит только зависимые фрагменты (рис. 3). Управляющий граф [1]
этого модуля изображен на рис. 4,а, из которого следует, что фрагмент 1 содержит
5 маршрутов, а фрагмент 2 - 3 маршрута. Так как каждый маршрут фрагмента 2
зависит от маршрутов фрагмента 1, то общее число маршрутов в данном модуле
равно произведению чисел маршрутов каждого из фрагментов, то есть
S = S1 * S2.
Рис.4. Расчетные маршрутные схемы (РМС):
а) управляющий граф модуля по рис.3,
б) РМС этого модуля,
в) РМС модуля по рис. 2,в.
Управляющий граф не очень удобен для рисования и подсчета общего числа
маршрутов модулей, фрагменты которых содержат сравнительно большое число
путей каждый. Поэтому вместо управляющего графа предлагается более простая
расчетная маршрутная схема (РМС) модуля (рис.4,б). В РМС прямоугольниками
обозначены: оператор начала - “нач”, оператор конца - “кон”, фрагмент n - “fn”.
В нижней части прямоугольника, обозначающего фрагмент, указано число путей в
данном фрагменте; в нижней части прямоугольника,обозначающего начало модуля
указана константа единица. Рядом с дугой, соединяющей два прямоугольника,
указывается число маршрутов, образованных всеми фрагментами, размещенными
последовательно от начала модуля до того фрагмента, в который входит
рассматриваемая дуга. В нижней части прямоугольника,обозначающего конец модуля,
указывается общее число путей в модуле. Фрагменты, имеющие единственный путь в
РМС не включаются.
В общем случае, общее число S путей последовательности из N зависимых
фрагментов определяется следующим образом:
S = S1 * S2 * ... * SN, где знак “*”
обозначает операцию произведения.
Рассмотрим теперь независимые фрагменты. Как уже упоминалось, независимые
фрагменты могут быть реализованы параллельно. Любой маршрут независимого
фрагмента не связан с другими фрагментами модуля, поэтому он анализируется
автономно. На рис. 4,в показана РМС модуля с двумя независимыми фрагментами.
Для модуля с независимыми фрагментами РМС выполняется в варианте параллельного
соединения фрагментов даже, если модуль реализован с последовательным включением
этих фрагментов. Числа, указанные в РМС на рис.4,в интерпретируются так же,
как и на рис. 4,б. Дополнительно поясним: дуги, исходящие из двойной черты
(распараллеливание процесса) отмечены тем же числом, что и заходящая в двойную
черту дуга; дуга, исходящая из жирной горизонтальной черты, обозначающей конец
распараллеливания, отмечается числом, равным сумме чисел, помечающих заходящие
в эту черту дуги. Тем самым устанавливается следующий факт.: общее число S
анализируемых путей модуля, содержащего только независимые фрагменты,
определяется суммой вида S = S1 + S2 + ... +
SN, где N - число независимых
фрагментов. Однако, реальный путь в последовательной программе проходит через
все фрагменты, невзирая на их независимость. Поэтому число R реальных путей
равно числу путей S, вычисленному из той посылки, что независимых фрагментов
в модуле нет.
Отметим, что пути в РМС с параллельным включением независимых фрагментов будем
называть условными, а величину S - числом условных (по умолчанию) путей, в
отличие от величины R - числа реальных путей в МЦП. При этом S < R.
Практически МЦП, включающие только независимые или только зависимые фрагменты
встречаются достаточно редко. Для расчета числа анализируемых путей в МЦП с
фрагментами обоих типов сначала устанавливается взаимозависимость фрагментов
и групп фрагментов, что покажем на примере.
На рис. 5,а представлен модуль из девяти фрагментов, последовательно
размещенных в соответствии с текстом последовательно реализуемой подпрограммы.
Через дробь после обозначения фрагмента указано число путей в нем. Отметим, что
произвольная группа следующих подряд фрагментов так же является фрагментом,
который будем обозначать перечислением в скобках обозначений составляющих
группу фрагментов. Пусть, например, имеет место следующая зависимость
фрагментов в модуле (рис. 5,а): фрагменты (f1,f2,f3) и (f4,f5,f6,f7,f8,f9)
независимы относительно начала и конца, фрагмент f3 сверху зависим от f1 (f2),
фрагменты f1 и f2 независимы относительно начала и фрагмента f3, фрагмент f5
сверху зависим от f4, фрагмент (f6,f7) сверху зависим от f5, фрагмент (f8,f9)
сверху зависим от f6 (f7), фрагменты f6 и f7 независимы относительно f5 и
(f8,f9), фрагменты f8 и f9 независимы относительно (f6,f7) и конца.
Рис.5. Модуль с зависимыми и относительно независимыми фрагментами (а) и
его РМС (б).
На основании изложенного получена РМС (рис. 5,б) и расчитано общее число
условных путей в модуле (рис. 5,а) S = 1545, в то время как реальное число
путей
R = 10 * 5 * 7 * 4 * 6 * 2 * 3 * 5 * 7 = 1764000
Данное число на три порядка (!) превосходит ранее полученное.
Таким образом независимость фрагментов позволяет значительно снизить число
анализируемых (условных) маршрутов в МЦП, а РМС облегчает соответствующий
расчет.
Введем для МЦП коэффициент Kn независимости: Кn = S / R. Он имеет пределы:
верхний, равный единице, (все фрагменты зависимые) и нижний, равный отношению
суммы числа путей фрагментов к R (все фрагменты независимы).
4. Число маршрутов во фрагментах, содержащих булевы операции
Ранее рассмотренные в примерах фрагменты содержали конструкции логического
или множественного выбора, в условных вершинах которых содержались элементарные
логические условия без знаков булевых операций “И” и “ИЛИ”. Поэтому число путей
фрагмента определялось визуально без дополнительных построений. Однако наличие
знаков булевых операций в логических выражениях требует построения специальной
схемы для расчета числа путей как для единичного значения выражения так и для
нулевого. В качестве такой схемы предлагается использовать линейный бинарный
граф [4] (ЛБГ). Построение ЛБГ и расчет числа путей, порождаемых логическим
выражением с булевыми операциями, рассмотрим на следующем примере.
Пусть в условной вершине некоторого фрагмента представлено сложное логическое
выражение вида
( Sin(a) == Cos(b) && (! c % 5 || d > 3) && (e <= exp(f) || func(g)) ).
Здесь указаны: операции сравнения (“==“, “>“, “<=“), деления по модулю (“%”),
булевы операции (“!” - инверсия, “&&” - И, “||” - ИЛИ), функции синуса,
косинуса, экспоненты и некоторой целочисленной функции (func). Введем понятие
“атом” - это подформула, ограниченная слева и справа знаками булевых операций.
В данном случае атомами являются следующие подформулы: Sin(a) == Cos(b),
c % 5, d > 3, e <= exp(f), func(g).
Если в формуле содержится знак инверсии перед заключенной в скобки булевой
операцией, то знак этой операции изменяется (И на ИЛИ и наоборот), а знак
инверсии исключается перед данной подформулой и ставится перед каждым членом
замененной операции. В данной формуле этого не требуется.
Для построения ЛБГ разместим атомы друг под другом в порядке обхода всей
формулы слева направо (рис. 6) и соединим их дугами, направленными вниз.
Атомы образуют вершины ЛБГ, а дуги - связь между соседними вершинами. Вслед
за последним (нижним) атомом разместим две вершины, соответствующие результатам
вычисления формулы - единичному и нулевому; нижний атом соединим дугами с
указанными новыми вершинами. Все ранее построенные дуги называются основными
дугами ЛБГ. Теперь построим дуги, называемые переходами.
Рис.6. ЛБГ и расчет числа его нулевых и единичных путей.
Переходы строятся по обе стороны от оси ЛБГ, образуемой основными дугами между
вершинами - атомами. Переходы строятся начиная с вершины, предшествующей
последнему атому (в нашем случае с вершины “e <= exp(f)”). Переход строится
на той стороне от оси, где расположена вершина “результат 1”, если в формуле
справа от соответствующего атома стоит знак ИЛИ. В примере это переходы от
атомов “e <= exp(f)” и “!c%5”.Переход строится на другой стороне от оси, если
в формуле справа от атома стоит знак И. Это переходы от атомов “d > 3” и
“Sin(a) == Cos(b)”. Переход направляется к расположенной на стороне его
построения вершине “результат 1(0)”, если упомянутый знак ИЛИ (И) принадлежит
внешней операции формулы. Это переходы от атомов “Sin(a) == Cos(b)” и “d > 3”.
В противном случае переход направляется к ниже расположенной вершине,
соответствующей атому, размещенному справа от закрывающей скобки,
ограничивающей операцию,которой принадлежит упомянутый знак ИЛИ (И), а если
такого атома нет - к вершине “результат”. Это переходы от атомов “! c % 5” и
“e <= exp(f)”. Знак булевой операции отрицания на расчет числа путей не
влияет, поэтому в построенном, следуя вышесказанному, ЛБГ он игнорируется
(см. рис. 6). Формальное описание синтеза ЛБГ представлено в [5].
Теперь рассмотрим процесс подсчета числа единичных и нулевых путей в
построенном ЛБГ. Будем использовать специальную метку, представляющую собой
два числа, разделенную знаком дроби. При этом левое число будет обозначать
число нулевых путей, а правое - единичных. Например, метка “3 / 5” показывает
три нулевых и пять единичных путей.
Логично предположить, что расчет числа путей надо начинать от начальной вершины.
Но предлагается более простой алгоритм подсчета, начиная с вершин “результат”.
Под вершиной “результат 0” поставим метку “1 / 0”, а под вершиной “результат 1”
- метку “0 / 1”. На каждой дуге, заходящей в вершину “результат” поставим
такую же соответствующую метку. Далее, для каждой вершины ЛБГ, начиная с
последнего атома и следуя вверх, выполнить следующее. Сложить метки “a0 / a1”
и “b0 / b1”, указанные на исходящих из данной вершины дугах, в результате чего
получится метка “c0 / c1”, где c0 = a0 + b0, c1 = a1 + b1. Полученную метку
поставить на каждой заходящей в данную вершину дуге. В результате над самой
верхней вершиной ЛБГ получается метка “s0 / s1”, где s0 - число нулевых путей,
то есть число путей, определяющих результат 0, а s1 - число единичных путей,
определяющих результат 1.
5. Число путей во фрагментах, содержащих циклические операторы
В структурированных программах циклические операторы могут быть сведены к двум
типам фрагментов: с проверкой условия цикла до входа в тело цикла и - после
тела цикла (рис. 7). Число S путей таких фрагментов определяется четырьмя
компонентами: числом Sp путей пролога цикла (где устанавливаются начальные
значения переменных, используемых в условии и в теле цикла), числом St тела
цикла ( в котором включим счетчики и другие операторы приращений) и числами S1
и S0 единичных и нулевых путей, соответственно, условия (“усл” на рис.7)
выполнения цикла.
Рис.7. Два типа циклических операторов.
В первом случае (рис. 7,а) тело цикла может не выполниться ни разу, при этом
анализируется S = Sp * S1 путей. Если условие выполнено хотя бы один раз, то
анализируется S = Sp * S1 * St * S0 путей. По максимуму принимаем последнее
выражение для определения числа путей в циклических операторах первого типа.
Во втором случае (рис. 7,б) тело цикла всегда выполняется хотя бы один раз,
даже, если условие не выполняется. При этом анализируется S = Sp * St * S0
путей. Если же условие цикла выполнится хотя бы один раз, то число путей
S = Sp * St * S0 * St * S1. С учетом того, что пути тела цикла анализируются
только один раз, получим S = Sp * St * S0 * S1.
Таким образом, для любого из двух представленных типов фрагментов с циклическими
операторами число анализируемых путей определяется выражением
S = Sp * St * S1 * S0.
6. Условно-независимые фрагменты
Кроме циклических операторов фрагменты могут быть образованы операторами
ветвления. Такими операторами являются условные (двоичного выбора) и операторы
множественного выбора. Пример фрагмента с оператором двоичного выбора показан
на рис. 2 (“фрагмент 1”). а с множественным выбором - на рис.3 (“фрагмент 2”).
Фрагменты операторов выбора включают вершину, в общем случае, с целочисленной
переменной (в том числе операция сравнения есть булева переменная с двумя
значениями), из этой вершины исходит по крайней мере две помеченые дуги,
заходящие в вершины, соответствующие операторам нижнего уровня и являющиеся
вложенными фрагментами, которые и будем называть условно-независимыми. Такое
название объясняется тем, что с позиции расчета числа путей эти вложенные
фрагменты не зависят друг от друга. Поэтому число путей во фрагменте с
оператором двоичного выбора определяется так: вычисляются числа единичных и
нулевых путей логического условия (при наличии булевых операций в нем),
считается число путей в каждом из условно-независимых фрагменте, которое
умножается на соответствующее число единичных (нулевых) путей, и полученные
произведения складываются. Для операторов недвоичного выбора просто складываются
числа путей условно-независимых фрагментов.
7. Структурный объем памяти модулей циклических программ
МЦП с памятью будем называть такой модуль, который обрабатывает локальные
статические переменные (ЛСП), область действия которых не выходит за рамки
данного модуля. При этом в МЦП формируется значение ЛСП в текущем глобальном
цикле, а анализируется это значение уже в следующем цикле. Пример такого модуля
представлен на рис.3, где переменная А есть ЛСП.
ЛСП усложняют анализ структуры модуля, так как при разборе очередного цикла
необходимо помнить значения этих переменных, полученные в предшествовавшем
цикле. Поэтому такого критерия как число маршрутов уже недостаточно. Введем
новый критерий структурной сложности для МЦП с памятью, названный структурным
объемом памяти (СОП) модуля. Введем обозначения: m - число ЛСП, используемых в
модуле, i - порядковый номер маршрута модуля, содержащего всего S маршрутов,
ai - число операций присваивания (инициализации, модификации) ЛСП
на i-ом маршруте. Значение СОП определяется выражением
где “max” - операция взятия максимума из двух переменных.
Здесь предполагается, что S вычислено по РСМ. Нижняя оценка СОП вычисляется в
предположении, что каждой переменной (ЛСП) на одном маршруте присваивается не
более одного нового значения: Pmin = m * S.
Для уменьшения СОП следует так изменить МЦП, чтобы уменьшилось число ЛСП и
число путей S. Этого можно добиться, создавая независимые или
условно-независимые фрагменты с заменой нескольких ЛСП, определяющих маршруты
фрагмента, на одну ЛСП с образованием множественного оператора выбора. Решение
данной задачи обеспечивается типовой реализацией МЦП, рассматриваемой ниже.
8. Реализация модулей циклических программ С-автоматами
В качестве типовой реализации МЦП с ЛСП предлагается использовать модель
С-автомата [6], ориентированную на программную реализацию. Применение моделей
конечных автоматов в программировании не ново (например, [7]). В частности
R-технология [8] использует модель автоматов Мили, а технология
программирования алгоритмов логического управления [9] использует модель
автоматов Мура. Программы различного профиля, в том числе и логического
управления, требуют, в общем случае, объединения указанных моделей в одну, то
есть использовать С-автомат [10].
Выбор конечно-автоматной реализации МЦП обусловлен, во-первых, универсальностью
(как правило, МЦП имеют не менее двух состояний), а, во-вторых, тем, что вместо
многих ЛСП, управляющих маршрутами в МЦП, может быть использована единственная
целочисленная ЛСП, каждое значение которой соответствует определенному
состоянию автомата. Это может существенно снизить значение СОП, например, до
величины S. В случае предлагаемой ниже типовой реализации число маршрутов легко
вычисляется по схеме алгоритма и поддается сравнительно легкой верхней оценке.
Алгоритм МЦП задается графом переходов С-автомата , пример которого изображен
на рис. 8. Граф содержит три вершины, отмеченные внутри прямоугольников, им
соответствующих, дробными отметками. В числителе указан идентификатор состояния
(символы a,b,c), который может быть либо целым произвольным числом либо
произвольным символом. В знаменателе указан идентификатор оператора (Za,Zb,Zc),
обязательно выполняющегося в данном состоянии. У вершины может быть петля,
также отмеченная дробъю, в числителе которой указано условие, например Xa, а
в знаменателе - идентификатор оператора, соответственно Ya, выполняющегося,
если условие Xa = 1 (без перехода в другое состояние). Вершины связаны дугами,
помеченные аналогично, например, дуга из состояния “a” в состояние “b”
отмечена дробью “Xab/Yab”, где Yab - оператор, выполняемый при наличии условия
Xab, и после реализации Yab новым состоянием автомата становится “b”. Условия,
помечающие дуги, исходящие из одной вершины, включая петлю, должны быть
попарно ортогональны.
Рис.8. Граф переходов С-автомата.
Практика программирования показывает, что, в общем случае, переход из одного
состояния, например из “а”, в другое состояние, например в “с”, может
осуществляться с реализацией не одного (Yac), а нескольких операторов,
следующих в соответствии с выполнением ряда условий. Например, по условию
Xac1 реализуется оператор Yac1, и выполняется переход из “а” в “с”; по условию
Xac2 реализуется оператор Yac2, и выполняется такой же переход. Ортогональных
условий вида Xack одинакового перехода из состояния “а” в состояние “с” с
реализацией соответствующих операторов вида Yack может быть несколько
(k = 1,2,...,Lac). Таким образом граф С-автомата, в общем случае, является
мультиграфом.
9. Типовая структура модуля, реализующего С-автомат
Типовая структура МЦП, реализующего С-автомат (согласно рис.8) представлена на
рис.9, где используется оператор множественного выбора [11] для определения
состояния Т автомата. При этом образуются три похожих условно-независимых
фрагмента, первый из которых включает компоненты (Za, Xa, Ya, Xab, Yab, Xac,
Yac). Этот фрагмент, в свою очередь, включает снизу-зависимый фрагмент Za.
Из этого следует достаточно простой расчет числа условных путей в МЦП:
S = D(Za) * [E(Xa) * D(Ya) + F(Xa) * E(Xab) * D(Yab) +
+ F(Xa) * F(Xab) * E(Xac) * D(Yac) + F(Xa) * F(Xab) * F(Xac)] +
+ D(Zb) * [E(Xb) * D(Yb) + F(Xb) * E(Xba) * D(Yba) +
+ F(Xb) * F(Xba) * E(Xbc) * D(Ybc) + F(Xb) * F(Xba) * F(Xbc)] +
+ D(Zc) * [E(Xc) * D(Yc) + F(Xc) * E(Xca) * D(Yca) +
+ F(Xc) * F(Xca) * E(Xcb) * D(Ycb) + F(Xc) * F(Xca) * F(Xcb)].
Здесь обозначены: D(Za) - число путей во фрагменте Za, E(Xa) - число единичных
путей в ЛБГ, реализующем логическое условие Xa, F(Xa) - число нулевых путей в
этом ЛБГ.
Рис.9. Структура МЦП, реализующего С-автомат
Если фрагменты Za,Ya, Yab, Yac и подобные им не включают в себя независимых
фрагментов, то число условных путей совпадает с числом реальных путей.
Если ЛСП Т (номер или символ состояния С-автомата) является единственной ЛСП в
этом МЦП, то СОП вычисляется тривиально: просто складываются число дуг и петель
с числом вершин графа переходов.
В общем случае, операторы Z и Y могут быть составными и/или включающими
обращения к подпрограммам, то есть любыми допустимыми в языке программирования
операторами.
10. Оптимизация структуры модуля, реализующего С-автомат
Если логические условия X содержат как операции И так и операции ИЛИ, то они
подлежат оптимизации по числу путей. При этом для каждого условия ищется такая
перестановка его членов, которая дает наименьшее значение числа путей, согласно
методу [12]. В результате оптимизации уменьшается число как единичных так и
нулевых путей в ЛБГ, реализующем условие X. Аналогично оптимизируются логические
условия, содержащиеся в операторах Z, Y. После оптимизации общее число путей в
МЦП должно уменьшиться.
Другой оптимизацией является повышение быстродействия МЦП. Самой простой
оптимизацией является переразмещение условно-независимых фрагментов,
начинающихся с операторов Z. Для этого определяются вероятности p(Za) ,
p(Zb), p(Zc) пребывания МЦП в состояниях “a”, “b”, “c” соответственно.
Затем условно-независимые фрагменты размещаются в операторе множественного
выбора согласно убыванию соответствующих им вероятностей p(Z).
Более сложной является оптимизация по быстродействию путем перестановок условий
Xa, Xab, Xac с соответствующими фрагментами Ya, (Yab,”T=b”) и так далее. Для
выполнения такой оптимизации полагаем, что задано исходное логическое выражение
вида “Xa || Xab || Xac”. В данном выражении следует выполнить оптимизирующую
перестановку членов согласно методу [13]. После этого указанные условия с
соответствующими фрагментами переставляются местами согласно оптимальной
перестановке выше приведенного логического выражения. Если критерий
быстродействия является доминирующим для программы, то оптимальные перестановки
по [13] следует получить как для каждого из логических выражений Xa, Xab, Xac
так и для логических выражений, входящих в операторы Z и Y.
11. Табличная реализация С-автомата
В случае, когда условия Xa, Xab, Xac представляют собой выражения вида
“V == v1”, “V == v2”, “V == v3”, соответственно, где V - переменная,
обозначающая, например, символ с клавиатуры или сообщение оконной функции
приложения для операционной системы Windows [14], а v1, v2, v3 - значения
переменной V, то состояние после перехода можно вычислить, используя табличный
метод [2,11]. При табличной реализации существенно уменьшается число
путей в МЦП.
Если, кроме того, операторы Z и Y представить в виде подпрограмм, то
предлагаемая ниже табличная реализация является наиболее эффективной.
Пусть a = 0, b = 1, c = 2, Xa: “V == 0”, Xab: “V == 1”, Xac: “V == 2”,
Xb: “V == 3” и так далее. Составим по графу переходов (рис.8) таблицу
переходов и сопоставим ей соответствующий программный двухмерный массив МП
(рис.10), строки которого соответствуют переменной V, а столбцы - переменной
состояния Т, элементами массива являются номера состояний после перехода.
Составим также таблицу 2 выходов Мили и сопоставим ей двухмерный массив ММ
(рис.10), строки которого соответствуют переменной V, а столбцы - переменной Т.
Если строки МП (ММ) имеют одинаковое значение V, то они склеиваются. Составим
вектор ВВ выходов Мура с элементами {Za, Zb, Zc}.
Рис.10. Массивы МП и ММ.
На основании изложенного структура МЦП (за исключением инициализации Т = 0 и
массивов ММ, МП, ВВ) принимает вид:
-
Преобразовать входное сообщение с помощью оператора множественного выбора в
значение переменной V;
-
Выполнить подпрограмму ВВ[T];
-
Выполнить подпрограмму MM[V][T];
-
T = МП[V][T].
-
Конец.
Проще по структуре МЦП трудно представить.
При этом S = R = P = 9 (по первой операции).
Список литературы
-
Липаев В.В. Качество программного обеспечения. - М.:
Финансы и статистика, 1983.
-
Майерс Г. Надежность программного обеспечения. - М.:
Мир, 1980.
-
Кузнецов Б.П. Структурирование бинарных программ. -
Вопросы судостроения. Сер. Судовая автоматика. - 1983, № 29, с. 27 - 35.
-
Кузнецов Б.П., Шалыто А.А. Реализация булевых формул линейными
бинарными графами. 1. Синтез и анализ. - Техническая кибернетика - 1994,
№ 5, с.132 - 142.
-
Кузнецов Б.П., Шалыто А.А. Система преобразований некоторых форм
представления булевых функций. - А и Т, 1985, № 11, с. 120 - 127.
-
Баранов С.И. Синтез микропрограммных автоматов. - Л.: Энергия, 1979.
-
Байцер Б. Архитектура вычислительных комплексов. Том 1. - М.: Мир, 1979
-
Вельбицкий И.В. и др. Технологический комплекс производства программ на
машинах ЕС ЭВМ и БЭСМ-6. - М.: Статистика, 1980.
-
Шалыто А.А. и др. Алгоритмизация и программирование задач логического
управления техническими средствами. - С.-Пб.:Моринтех, 1996.
-
Кузнецов Б.П. Стандартная реализация управляющих программ. - Судостроительная
промышленность. Сер. Системы автоматизации проектирования, производства и
управления. 1986, вып. 1, с.51 - 55.
-
Джамп Д. AutoCAD. Программирование. - М.: Радио и связь, 1992.
-
Кузнецов Б.П., Шалыто А.А. Реализация булевых формул линейными бинарными
графами. III. Оптимизация числа и суммарной длины путей. -
Теория и системы управления, 1995, № 5, с. 214 -223.
-
Кузнецов Б.П. Длительность вычислений на линейных бинарных графах. - А и Т,
1994, № 9, с. 166 - 172.
-
Петзолд Ч. Программирование для Windows 95. Том I. - СПб.: BHV -
Санкт-Петербург, 1997.
|