ПРЕДИСЛОВИЕ Этот сборник приурочен сразу к двум юбилеям, важным для Института системного программирования (ИСП РАН): 275 лет Российской академии наук и пять лет со дня создания Института. Именно поэтому статьи этого сборника подводят итоги исследовательских работ сотрудников Института за пять лет. Немного информации об истории и области деятельности Института. ИСП РАН был образован 25 января 1994 г. в день святой Татьяны, покровительницы Московского государственного университета и всех российских студентов. Несмотря на такой молодой возраст, Институт базируется на группе специалистов, которые работали совместно в течение более 30 лет (ИТМ и ВТ, НИИ "Дельта", ИПК АН). Группа начинала свою активность в области операционных систем (НД-70 для БЭСМ-6, операционная система для АС-6 и т.д.), а также в области компиляторов для различных языков (ассемблер, Фортран, расширенный BCPL, ПЛ/1 и т.д.). Конечно, в связи с требованиями сегодняшнего мира задачи Института несколько иные. Что мы реально делаем? Имеются три основных направления: • Фундаментальные исследования в базовых областях Computer Science • Разработка прототипных и готовых к использованию программных систем • Обучение студентов и аспирантов. Можно много говорить по поводу каждого из направлений. Но в данном сборнике мы решили сосредоточиться на исследованиях Института. Основными темами, в которых за последние годы получены серьезные результаты, являются следующие: • системы параллельного программирования в неоднородных вычислительных сетях; • использование формальных методов для прямой и обратной инженерии программных систем; • системы автономного адаптивного управления; • объектно-ориентированные распределенные информационные системы; • объектно-ориентированные системы визуализации; • эффективные вычислительные алгоритмы. Надеюсь, что содержащиеся в сборнике статьи дадут читателям достаточную информацию об исследовательской деятельности Института. Директор ИСП РАН, член-корреспондент РАН
В.П.Иванников
Язык и система программирования для высокопроизводительных параллельных вычислений на неоднородных сетях А.Л. Ластовецкий, А.Я. Калинов, И.Н. Ледовских, Д.М. Арапов, М.А. Посыпкин
Аннотация В статье описывается язык mpC, разработанный специально для программирования высокопроизводительных вычислений на неоднородных сетях компьютеров. Программа на mpC явно определяет абстрактную вычислительную сеть и распределяет данные, вычисления и коммуникации по этой сети. Система программирования mpC в период выполнения программы использует эту информацию и информацию о реальной сети, выполняющей программу, для такого размещения процессов программы на физической сети, которое обеспечивало бы эффективное выполнение программы. Описывается опыт использования mpC для решения задач на локальных сетях неоднородных рабочих станций.
1. Введение Еще 10 лет назад к высокопроизводительным параллельным вычислительным системам относили лишь так называемые суперкомпьютеры - мультипроцессоры с общей памятью (SMP) и мультипроцессоры с распределенной памятью (MPP). Параллельные вычисления на обычных сетях рабочих станций и персональных компьютеров не имели смысла, поскольку не могли ускорить решение большинства задач из-за низкой производительности типового сетевого оборудования. Однако с начала 1990х годов рост производительности типового сетевого оборудования уже устойчиво обгоняет рост производительности процессоров [1], (pp.6-7). Современные сетевые технологии, такие как Fast Ethernet, ATM, Myrinet и другие, уже обеспечивают обмен данными между компьютерами на уровне сотен мегабит и даже нескольких гигабит в секунду. Это привело к ситуации, когда не только специализированные параллельные компьютеры, но и обычные локальные и даже глобальные сети можно использовать в качестве параллельных вычислительных систем для высокопроизводительных вычислений. Объявленная президентом США стратегическая
инициатива, направленная на тысячекратное ускорение обмена данными в сети Internet и поддержанная ведущими компаниями (телекоммуникационными и компьютерными), ясно указывает на наметившийся сдвиг высокопроизводительных вычислений в сторону сетевых вычислений. Таким образом, в настоящее время сети компьютеров являются самой доступной и распространенной параллельной архитектурой и, зачастую, необходимое ускорение решения тех или иных задач может быть достигнуто не путем приобретения нового более мощного компьютера, а за счет использования вычислительного потенциала уже имеющихся компьютеров, связанных с помощью современного сетевого оборудования. Использование сетей для параллельных высокопроизводительных вычислений сдерживается лишь отсутствием подходящего программного обеспечения. Дело в том, что, в отличие от суперкомпьютеров, сети по своей природе неоднородны и состоят из разнообразных компьютеров обычно различной производительности, связанных в сеть иногда неоднородным сетевым оборудованием, предоставляющим разную скорость обмена данными между разными процессорными узлами. Как правило, параллельная программа, перенесенная с (однородного) суперкомпьютера, выполняется на неоднородной сети с той же скоростью, с какой она выполнялась бы на однородной сети, состоящей из процессоров эквивалентных по производительности слабейшему процессору исходной неоднородной сети, число которых равно числу процессоров исходной неоднородной сети. Объясняется это тем, что такие параллельные программы распределяют данные, вычисления и коммуникации без учета различий в производительности процессоров и коммуникационных линков. Это резко снижает эффективность использования производительного потенциала сетей и приводит к крайне незначительному их использованию для высокопроизводительных параллельных вычислений.
6 В настоящее время основными средствами параллельного программирования для сетей являются MPI [2], PVM [3] и HPF [4]. PVM (Parallel Virtual Machine) и MPI (Message Passing Interface) - это библиотеки передачи сообщений, являющиеся, по сути, средствами уровня ассемблера для параллельного программирования. Из-за низкого уровня их параллельных примитивов разработка на PVM/MPI не учебных, а практически полезных и сложных программ представляет собой крайне трудную задачу и требует очень высокой квалификации разработчика. Кроме того, эти библиотеки не проектировались для разработки адаптивных параллельных программ, то есть программ, распределяющих вычисления и коммуникации в зависимости от входных данных и особенностей конкретной исполняющей неоднородной сети. Конечно, благодаря их низкому уровню, у пользователя есть возможность написать специальную систему времени выполнения, обеспечивающую адаптируемость его программы, однако такая система, как правило, настолько сложна, что необходимость ее разработки способна отпугнуть большинство нормальных пользователей. HPF (High Performance Fortran) представляет собой параллельный язык высокого уровня, первоначально спроектированный для программирования (однородных) суперкомпьютеров. Поэтому единственной параллельной архитектурой, видимой при программировании на HPF, является однородный мультипроцессор с очень быстрыми коммуникационными линками между его процессорами. HPF не поддерживает нерегулярное распределение данных, неоднородное распределение данных, а также среднеблочный параллелизм. Типичный компилятор языка HPF транслирует программу на HPF в программу на PVM или MPI, и программист не может влиять на сбалансированность процессов целевой программы передачи сообщений. Кроме того, HPF очень труден для компиляции. Даже лучшие компиляторы HPF генерируют код, в среднем в 23 раза медленнее выполняемый на однородных кластерах рабочих станций, чем вручную написанный на MPI (по материалам конференции пользователей HPF [5], состоявшейся в июне 1998 года в Порто, Португалия). Поэтому HPF также не вполне подходит для программирования высокопроизводительных вычислений на сетях. Таким образом, нужны новые, специальные инструментальные средства, которые бы позволили эффективно использовать неоднородные сети компьютеров в качестве параллельных вычислительных систем с распределенной памятью.
В статье описывается первый параллельный язык, специально спроектированный для программирования неоднородных сетей, а также поддерживающая его система программирования. Этот язык, названный mpC, представляет собой расширение ANSI C. Подобно HPF, он включает векторное подмножество [6]. Известные языки параллельного программирования ориентированы на программирование регулярных параллельных архитектур, параметризуемых с помощью небольшого числа параметров. Регулярность целевых архитектур позволяет неявно встраивать их в эти языки. Этот традиционный подход неприменим к проектированию параллельного языка, ориентированного на неоднородные сети, поскольку эта архитектура не имеет регулярной структуры. Основная идея, лежащая в основе языка mpC, заключается в предоставлении пользователю языковых конструкций, позволяющих ему определять абстрактную неоднородную параллельную машину, наиболее подходящую для выполнения его алгоритма. Эта информация вместе с информацией о физической параллельной системе используется системой программирования mpC для обеспечения эффективного выполнения соответствующей программы на этой физической параллельной системе. Статья построена следующим образом. Раздел 2 дает введение в mpC. Раздел 3 кратко описывает принципы реализации. В разделе 4 обсуждаются проблемы оценки характеристик параллельной вычислительной системы, на которой выполняется программа. Раздел 5 описывает опыт использования mpC для разработки реальных приложений. В разделе 6 описываются похожие работы. Раздел 7 содержит заключение.
2. Введение в mpC В языке mpC вводится понятие вычислительного пространства, которое определяется как некоторое доступное для управления множество виртуальных процессоров различной производительности, связанных линками с различной скоростью передачи. Основным понятием mpC является понятие сетевого объекта или просто сети. Сеть состоит из виртуальных процессоров различной производительности, связанных между собой линками с различной скоростью передачи. Сеть является областью вычислительного пространства, которая может быть использована для вычисления выражений и выполнения операторов. Размещение и освобождение сетевых объектов в вычислительном пространстве выполняется в аналогичной манере с размещением и освобождением объектов данных в памяти в языке C. Концептуально, создание новой сети
7 инициируется процессором уже существующей сети. Этот процессор называется родителем создаваемой сети. Родитель всегда принадлежит создаваемой сети. Единственным процессором, определенным от начала и до конца выполнения программы, является предопределенный виртуальный хост-процессор. Любой сетевой объект, объявленный в программе, имеет тип. Тип специфицирует число, типы и производительности процессоров, линки между процессорами и их скорости, а также родителя сети. Например, объявление
координатами [I] и [3]. Отметим, что если линк между двумя процессорами не специфицирован явно, то это означает наличие между ними линка с минимальной для данной сети скоростью. Строка 8 содержит объявление родителя. Она специфицирует, что родительский процессор имеет координату [0] в создаваемой сети. Имея объявление сетевого типа, можно объявить идентификатор сетевого объекта этого типа. Например, объявление
/* /* /* /* /* /* /* /* /*
вводит идентификатор r1 сетевого объекта типа Rectangle. Понятие распределенного объекта вводится в стиле языков C* [7] и Dataparallel C [8]. По определению, объект данных, распределенный по некоторой области вычислительного пространства, составляется из обычных (нераспределенных) объектов одного типа (называемых компонентами распределенного объекта данных), размещенных в процессорных узлах этой области таким образом, что каждый процессорный узел содержит одну и только одну компоненту. Например, объявления
Строка Строка Строка Строка Строка Строка Строка Строка Строка
1 2 3 4 5 6 7 8 9
*/ */ */ */ */ */ */ */ */
nettype Rectangle { coord I=4; node { I>=0 : I+1; }; link { I>0: [I]<->[I-1]; I==0: [I]<->[3]; }; parent [0]; };
вводит сетевой тип с именем Rectangle, соответствующий сетям, состоящим из четырех виртуальных процессоров различной производительности, связанных в прямоугольник ненаправленными линками с обычной скоростью. Здесь строка 1 содержит заголовок объявления сетевого типа. Она вводит имя сетевого типа. Строка 2 содержит объявление системы координат, к которой привязываются процессоры. Она вводит целую координатную переменную I со значениями от 0 до 3. Строка 3 содержит объявление процессорных узлов. Оно привязывает процессоры к системе координат и объявляет их типы и производительности. Строка 3 соответствует предикату для всех I<4 если I>=0, то виртуальный процессор с относительной производительностью, определяемой величиной I+1, привязывается к точке с координатой [I]. Выражение I+1 называется спецификатором производительности. Большее число задает большую производительность. В примере 0-й виртуальный процессор в два раза медленней, чем 1-й, в три раза медленнее, чем 2-й и в четыре раза медленнее, чем 3-й виртуальный процессор. Для любой сети такого типа эта информация позволяет компилятору приписать каждому виртуальному процессору его вес, нормализованный относительно родительского узла сети. Строки 4-7 содержат объявление линков. Оно специфицирует линки между процессорами. Строка 5 соответствует предикату для всех I<4 если I>0 то имеется ненаправленный линк с обычной скоростью, связывающий процессоры с координатами [I] и [I-1], а строка 6 соответствует предикату для всех I<4 если I==0 то имеется ненаправленный линк с обычной скоростью, связывающий процессоры с
net Rectangle r1;
net Rectangle r2; int [*]Derror, [r2]Da[10]; float [host]f, [r2:I<2]Df; repl [*]di;
вводят: • целую переменную Derror, распределенную по всему вычислительному пространству; • массив Da из десяти целых, распределенный по сети r2; • нераспределенную вещественную переменную f, принадлежащую виртуальному хостпроцессору; • вещественную переменную Df, распределенную по подсети сети r2; • целую переменную di, размазанную по всему вычислительному пространству. По определению, распределенный объект является размазанным, если все его компоненты равны между собой. Понятие распределенного значения вводится аналогично понятию распределенного объекта данных. Кроме простого сетевого типа, можно объявлять параметризованное семейство сетевых типов, называемое топологией или параметризованным сетевым типом. Например, объявление /* { /* /* /* /* /* /*
Строка 1 */
nettype Ring(n, p[n])
Строка Строка Строка Строка Строка Строка
coord I=n; node { I>=0: p[I]; }; link { I>0: [I]<->[I-1];
2 3 4 5 6 7
*/ */ */ */ */ */
8 /* /* /* /*
Строка Строка Строка Строка
8 */ 9 */ 10 */ 11 */
I==0: [I]<->[n-1]; }; parent [0]; ;
вводит топологию с именем Ring, соответствующую сетям, состоящим из n виртуальных процессоров, связанных в кольцо с помощью ненаправленных линков с нормальной скоростью. Заголовок объявления (строка 1) вводит параметры топологии Ring, а именно, целый параметр n и векторный параметр p, состоящий из n целых. Соответственно, координатная переменная I пробегает значения от 0 до n-1, строка 4 соответствует предикату для всех I
=0, то виртуальный процессор с относительная производительностью, специфицируемой значением p[I], привязывается к точке с координатами [I] и т.п. Имея объявление топологии, можно объявить идентификатор сетевого объекта подходящего типа. Например, фрагмент repl [*]m,[*]n[100]; /* Вычисление m, n[0], ..., n[m-1] */
net Ring(m,n) r;
вводит идентификатор rr сетевого объекта, чей тип определяется полностью только во время выполнения программы. Сеть rr состоит из m виртуальных процессоров. Относительная производительность i-го виртуального процессора определяется значением n[i]. Сетевой объект характеризуется классом вычислительного пространства, выделенного для него и определяющего время его жизни. Область вычислительного пространства может выделяться статически или автоматически. Вычислительное пространство под статическую сеть отводится один раз. Будучи созданной, сеть существует до конца выполнения программы. Новый экземпляр сети, описанной как автоматическая, создается при каждом входе в блок, в котором сеть описана, и уничтожается при каждом выходе из блока. Рассмотрим простую mpC программу умножения двух плотных квадратных матриц X и Y, использующую несколько виртуальных процессоров, каждый из которых вычисляет часть строк результирующей матрицы Z. /* 1 */ #include <stdio.h> /* 2 */ #include <stdlib.h> /* 3 */ #include <mpc.h> /* 4 */ #define N 1000 /* 5 */ void [host]Input(), [host]Output(); /* 6 */ nettype Star(m, n[m]) { /* 7 */ coord I=m; /* 8 */ node { I>=0: n[I]; }; /* 9 */ link { I>0: [0]<->[I]; }; /* 10*/ }; /* 11*/ void [*]main()
/* 12*/ { /* 13*/ double [host]x[N][N], [host]y[N][N], [host]z[N][N]; /* 14*/ repl int nprocs; /* 15*/ repl double *powers; /* 16*/ Input(x, y); /* 17*/ MPC_Processors(&nprocs, &powers); /* 18*/ { /* 19*/ repl int ns[nprocs]; /* 20*/ MPC_Partition_1b(nprocs, powers, ns, N); /* 21*/ { /* 22*/ net Star(nprocs, ns) w; /* 23*/ int [w]myn; /* 24*/ myn=([w]ns)[I coordof myn]; /* 25*/ { /* 26*/ repl int [w]i, [w]j; /* 27*/ double [w]dx[myn][N],[w]dy[N][N], [w]dz[myn][N]; /* 28*/ dy[]=y[]; /* 29*/ dx[]=::x[]; /* 30*/ for(i=0; i<myn; i++) /* 31*/ for(j=0; j
Программа включает в себя 5 функций: main, приведенную выше, Input и Output, определенные в других исходных файлах, и библиотечные функции MPC_Processors и MPC_Partition_1b. Функции Input и Output объявляются в строке 5, а функции MPC_Processors и MPC_Partition_1b объявляются в файле mpc.h. В общем случае, mpC допускает 3 класса функций. В этом примере используются функции всех трех видов: main относятся к классу базовых функций, Input и Output к классу сетевых функций и MPC_Processors и MPC_Partition_1b к классу узловых функций. Вызов базовой функции всегда является тотальным выражением(то есть оно вычисляется на всем вычислительном пространстве; никакие другие вычисления не могут выполняться параллельно с вычислением тотального выражения). Ее аргументы, если таковые имеются, либо принадлежат хост-процессору, либо распределены по всему вычислительному пространству, a возвращаемое значение (если таковое имеется) распределено по всему вычислительному пространству. В отличие от других видов функций, базовая функция может содержать определения сетей. В строке 11 конструкция [*], помещенная перед
9 идентификатором функции main, специфицирует, что объявляется идентификатор базовой функции. Узловая функция может быть полностью выполнена на любом одном процессоре вычислительного пространства. В ней могут создаваться только локальные объекты данных виртуального процессора, на котором она вызывается, кроме которых могут использоваться и компоненты внешних объектов данных, принадлежащие этому процессору. Объявление идентификатора узловой функции не требует никаких дополнительных спецификаторов. С точки зрения mpC все обычные функции языка Си являются узловыми. В общем случае, сетевая функция вызывается и выполняется на некоторой области вычислительного пространства, и ее аргументы и возвращаемое значение, если таковые имеются, также распределены по этой же области. Две сетевые функции могут выполняться параллельно, если области, на которых они вызваны, не пересекаются. Функции Input и Output представляют собой простейшую форму сетевой функции, которая может быть вызвана только на статически определенной области вычислительного пространства. Они объявлены в строке 5 как сетевые функции, которые могут быть вызваны и выполнены только на виртуальном хост-процессоре (это задается конструкцией [host], помещенной непосредственно перед идентификаторами функций). Поэтому вызовы функций в строках 16 и 36 выполняются на виртуальном хостпроцессоре. Строки 11-38 содержат определение функции main. Строка 13 содержит определение массивов x, y и z, принадлежащих виртуальному хостпроцессору. Строка 14 определяет целую переменную nprocs, размазанную по всему вычислительному пространству. Ее распределение определяется правилом умолчания без помощи конструкции [*]. В общем случае, распределение по умолчанию задается распределением наименьшего блока, объемлющего соответствующее объявление и имеющего явно определенное распределение. Определение в стоке 14 содержится в теле функции main, для которой явно задано распределение по всему вычислительному пространству. Строка 15 определяет распределенную по всему вычислительному пространству переменную powers типа указатель на вещественное число. Объявление определяет, что все распределенные объекты данных, на которые указывает powers, являются размазанными. В строке 17 библиотечная узловая функция
MPC_Processors, возвращая число физических процессоров и их производительности вызывается на всем вычислительном пространстве (механизм оценки производительности процессоров описан в разделе 4). Таким образом, сразу после этого вызова размазанная переменная nprocs содержит число физических процессоров, а размазанный массив powers содержит их производительности. Строка 19 определяет динамический целый массив ns, размазанный по всему вычислительному пространству. Все компоненты массива состоят из одинакового числа элементов nprocs. В строке 20 библиотечная узловая функция MPC_Partition_1b вызывается на всем вычислительном пространстве. Основываясь на производительностях физических процессоров, эта функция вычисляет, сколько строк результирующей матрицы будет вычисляться каждым из физических процессоров. Таким образом, сразу после этого вызова ns[i] содержит число строк, вычисляемое i-ым физическим процессором. MPC_Partition_1b разбивает данное целое (N в приведенном выше вызове) на части в соответствии с заданной пропорцией. В строке 22 определяется автоматическая сеть w, состоящая из nprocs виртуальных процессоров. Относительная производительность i-го виртуального процессора определяется значением ns[i]. Таким образом, тип этой сети определяется полностью только в период выполнения. Эта сеть, выполняющая остальные вычисления и обмены данными, определяется таким образом, что чем мощнее виртуальный процессор, тем большее число строк он вычисляет. Система программирования mpC будет обеспечивать оптимальное отображение виртуальных процессоров, образующих сеть w, во множество процессов, представляющих вычислительное пространство. Таким образом, в точности один процесс из процессов, выполняющихся на каждом из физических процессоров, будет вовлечен в умножение матриц, и чем мощнее будет соответствующий физический процессор, тем большее число строк он будет вычислять. Строка 23 определяет переменную myn, распределенную по w. Результатом бинарной операции coordof в строке 24 будет целое значение, распределенное по w, каждая компонента которого равна значению координаты I виртуального процессора, которому эта компонента принадлежит. Правый операнд операции не вычисляется, а используется для спецификации
10 области вычислительного пространства. Заметим, что координатная переменная I интерпретируется как целая переменная, распределенная по области вычислительного пространства. Таким образом, после выполнения оператора в строке 24 каждая компонента myn содержит число строк результирующей матрицы, вычисляемое виртуальным процессором, которому она принадлежит. Строка 26 определяет целые переменные i и j размазанные по сети w. Строка 27 определяет три массива, распределенных по сети w. Тип dy определен статически как массив из N массивов из N вещественных чисел. Тип dx и dz динамически определяется как массив из myn массивов из N вещественных чисел. Заметим, что размерность myn массивов dx и dz не одинакова для различных компонент этих массивов. Строка 28 содержит необычный унарный постфиксный оператор []. Дело в том, что, строго говоря, mpC является расширением векторного расширения ANSI C называемого C[] [14], в котором введено понятие вектора как упорядоченной последовательности значений некоторого одного типа. В отличие от массива, вектор является не объектом данных, а новым видом значения. В частности, значением массива является вектор. Оператор [] был введен для доступа к массиву как целому. Он имеет операнд типа "массив" и блокирует преобразование операнда к указателю. Таким образом, y[] обозначает массив y как один объект, а dy[] обозначает распределенный массив dy как один объект. Оператор в строке 28 рассылает матрицу Y от родителя сети w всем виртуальным процессорам этой сети. В результате каждая компонента распределенного массива, на который указывает dy, будет содержать эту матрицу. В общем случае, если левый операнд оператора = распределен по некоторой области вычислительного пространства R, значение правого операнда принадлежит некоторой области вычислительного пространства, объемлющей R и присвоение может быть произведено без преобразования типов, то выполнение оператора заключается в посылке значения правого операнда к каждому виртуальному процессору области R, где оно присваивается соответствующей компоненте левого операнда. Оператор в строке 29 рассылает матрицу X с виртуального хост-процессора по всем виртуальным процессорам сети w. В результате каждая компонента dx содержит соответствующую порцию матрицы X. В общем случае первым операндом 4-
хместной операции =:: должен быть массив, распределенный по некоторой области R, состоящей из NP виртуальных процессоров. Остальные операнды (второй и третий могут отсутствовать) нераспределенные и принадлежат одному процессору. Второй операнд - необязательный, но если имеется, то должен либо указывать на начальный элемент NPэлементного целого массива, либо на NPэлементный целый массив. Третий операнд тоже необязательный и должен либо указывать на указатель на начальный элемент NP-элементного целого массива, значение i-го элемента которого не должно быть больше числа элементов i-й компоненты первого операнда, либо указывать на такой массив. Четвертый операнд должен быть массивом, значения элементов которого могут быть без преобразования типа присвоены любому элементу любой компоненты первого операнда. Выполнение e1=e2:e3:e4 заключается в вырезании NP подмассивов (возможно, перекрывающихся) из массива e4 и посылке значения i-го подмассива i-му виртуальному процессору области R, где оно присваивается соответствующей компоненте распределенного массива e1. Смещение i-го подмассива относительно начального элемента массива e4 задается значением i-го элемента массива e2, а его длина - значением i-го элемента массива e3. Если e3 указывает на пустой указатель (имеющий значение NULL), то операция выполняется, как если бы *e3 указывало бы на начальный элемент N-элементного целого массива, значение i-го элемента которого равняется длине i-ой компоненты распределенного массива e1. Более того, в этом случае такой массив действительно создается в результате выполнения операции, а указатель на его начальный элемент присваивается *e3. Если e2 указывает на пустой указатель (имеющий значение NULL), то операция выполняется, как если бы *e2 указывало бы на начальный элемент N-элементного целого массива, значение нулевого элемента которого равняется 0, а значение i-го элемента равняется сумме значения его (i-1)-го элемента и значения iго элемента массива e3. Более того, в этом случае такой массив действительно создается в результате выполнения операции, а указатель на его начальный элемент присваивается *e2. Второй операнд операции может быть опущен. В этом случае операция выполняется, как если бы e2 указывало на пустой указатель. Единственное различие заключается в том, что созданный в ходе выполнения NP-элементный массив освобождается. Третий операнд операции может быть опущен. В этом случае операция выполняется, как если бы
11 e3 указывало на пустой указатель. Единственное различие заключается в том, что созданный в ходе выполнения N-элементный массив освобождается. Таким образом, dx[]=::x[] в строке 29 приводит к разделению N-элементного массива x массивов из N вещественных чисел на nprocs подмассивов таким образом, что длина i-го подмассива равна значению компоненты myn, принадлежащей i-му виртуальному процессору (то есть значению [w:I==i]myn). Эта же операция будет выполнена быстрее, если использовать форму dx=:&ns:x, что позволит избежать дополнительных (и излишних в этом случае) коммуникаций и вычислений необходимых для формирования опущенных операндов. Асинхронный оператор (то есть оператор не требующий коммуникаций между виртуальными процессорами) в строках 30-32 параллельно вычисляет соответствующую порцию результирующей матрицы Z на каждом из виртуальных процессоров сети w. И, наконец, оператор в строке 32 собирает эти порции на виртуальном хост-процессоре, формируя результирующий массив z, с помощью оператора сборки ::=. Эта 4-х местная операция соответствует операции рассылки и выполняет подобным образом обратные коммуникационные операции.
3. Реализация mpC В настоящее время, система программирования mpC включает компилятор, систему поддержки времени выполнения, библиотеку и командный пользовательский интерфейс. Компилятор транслирует текст исходной программы на mpC в ANSI C программу с обращениями к функциям системы поддержки времени выполнения. Используется либо SPMD модель целевого кода, когда все процессы, составляющие параллельную программу выполняют одинаковый код или квази-SPMD модель, когда исходный mpC файл транслируется в два различных файла - один для виртуального хост-процессора и второй для остальных виртуальных процессоров. Система поддержки времени выполнения управляет вычислительным пространством, которое состоит из некоторого числа процессов, выполняющихся на целевой вычислительной машине с распределенной памятью (например, на сети ПК и рабочих станций), а также обеспечивает передачу сообщений. Она полностью инкапсулирует конкретный коммуникационный пакет (в настоящее время, MPI 1.1) и обеспечивает независимость
компилятора от конкретной целевой платформы. Библиотека состоит из функций, поддерживающих отладку программ, доступ к характеристикам вычислительного пространства, а также доступ к эффективным средствам низкого уровня. Командный пользовательский интерфейс состоит из некоторого числа команд для создания виртуальной вычислительной машины с распределенной памятью и выполнении mpCпрограмм на этой машине. При создании виртуальной параллельной машины ее топология (в частности, число и производительности процессоров, характеристики коммуникационных связей между процессорами) определяется автоматически в процессе выполнения специальной тестовой программы и полученная информация сохраняется в специальном файле, используемом в дальнейшем системой поддержки времени выполнения. 3.1 Модель целевой программы Все процессы, составляющие выполняющуюся целевую программу, разбиваются на две группы специальный процесс, называемый диспетчером и играющий роль управляющего вычислительным пространством, и обычные процессы, называемые узлами и играющие роль виртуальных процессоров вычислительного пространства. Диспетчер работает как сервер, принимая запросы от узлов. Диспетчер не принадлежит вычислительному пространству. В целевой программе каждая сеть или подсеть исходной mpC-программы представляется некоторым множеством узлов, называемым областью. В любой момент времени выполнения целевой программы каждый узел либо является свободным, либо включенным в одну или несколько областей. Узел, включенный в какуюлибо область, называется занятым. Включением узлов в область и их освобождением занимается диспетчер. Единственным исключением является специальный узел, называемый хостом и играющий роль виртуального хост-процессора. Непосредственно после инициализации вычислительное пространство представляется хостом и множеством свободных узлов. Основная проблема в управлении процессами состоит в их включении в область и освобождении. Решение этой проблемы определяет общую структуру целевого кода и формирует требования к функциям системы поддержки времени выполнения. Для создания области, представляющей сеть, (сетевой области) родительский узел вычисляет, если надо, топологические характеристики сети и передает диспетчеру запрос на создание области. Запрос содержит число узлов и их относительные производительности. Со своей стороны,
12 диспетчер хранит информацию относительно целевой сети компьютеров, включающую число актуальных процессоров, их относительные производительности и число узлов на актуальных процессорах. Базируясь на этой топологической информации, диспетчер выбирает множество свободных узлов, наиболее подходящих для создаваемой сетевой области. После этого диспетчер посылает всем свободным узлам сообщение, говорящее, включены они в создаваемую область или нет. Для освобождения сетевой области ее родительский узел посылает запрос диспетчеру на освобождение области. Заметим, что этот родительский узел остается включенным в родительскую сетевую область освобождаемой области. Остальные узлы освобождаемой области становятся свободными и начинают ожидать команду от диспетчера. Каждый узел может определить, занят ли он. Узел является занятым, если вызов на нем функции MPC_Is_busy() возвращает 1, и свободным, если вызов возвращает 0. Каждый узел может определить, занят ли он в конкретной области или нет. Доступ к области осуществляется через ее дескриптор. Если дескриптор rd соответствует некоторой области, то любой узел вычислительного пространства принадлежит этой области тогда и только тогда, когда вызов функции MPC_Is_member(&rd) на этом узле возвращает значение 1. В этом случае дескриптор rd позволяет узлу получать всю информацию о соответствующей области, а также идентифицировать себя внутри нее. Когда свободный узел включается в сетевую область, диспетчер должен сказать ему, в какую именно область он включается, то есть указать ее дескриптор. Простейший способ - разослать указатель на дескриптор от родительского узла не применим для машин с распределенной памятью, не имеющих общего адресного пространства. Поэтому необходим дополнительный идентификатор создаваемой сети, имещий одинаковое значение на родительском и свободных узлах и имеющий форму, допускающую пересылку от родительского узла к свободным через диспетчер. В исходной mpC программе сеть указывается своим именем, которое является обычным идентификатором и подчиняется обычным правилам видимости языка C. Поэтому имя сети не может служить уникальным идентификатором сети даже внутри одного файла. Можно перенумеровать все сети внутри файла и использовать этот номер как уникальный идентификатор сети в файле. Однако такой уникальный внутри файла идентификатор не будет уникальным во всей программе, которая может состоять из нескольких исходных файлов.
Однако он может использоваться при создании сети, если все узлы, участвующие в создании сети выполняют целевой код, соответствующий одному и тому же исходному файлу mpC программы. Такая схема и используется в нашем компиляторе. Все сети в файле нумеруются, а структура программы гарантирует, что при создании сети все участвующие узлы выполняют код, содержащийся в одном и том же файле. В создании области, представляющей сеть (сетевой области), участвуют родительский узел, диспетчер и все свободные узлы. При этом родительский узел вызывает функцию MPC_Net_create(MPC_Name name, MPC_Net* net);
где name содержит уникальный номер создаваемой сети в файле и net указывает на соответствующий дескриптор области. Функция вычисляет всю необходимую топологическую информацию и посылает запрос на создание сети диспетчеру. В это время свободные узлы ожидают команды от диспетчера в так называемой точке ожидания, вызвав функцию MPC_Offer(MPC_Names* names, MPC_Net** nets_voted, int voted_count);
где names это массив номеров сетей, создание которых возможно в этой точке ожидания, nets_voted массив указателей на дескрипторы областей, создание которых возможно в этой точке ожидания, и voted_count содержит число таких областей. Соответствие между номером сети и дескриптором области устанавливается следующим образом. Если свободный узел получил сообщение, что он включен в сеть с номером, равным names[i], то он включен в сетевую область, на дескриптор которой указывает nets_voted[i]. Свободные узлы возвращаются их функции ожидания MPC_Offer либо после того, как их включают в сетевую область, либо после того, как они получают от диспетчера команду покинуть точку ожидания. 3.2 Структура целевого кода для mpC блока В общем случае, в коде целевого блока с определениями сети имеются две точки ожидания. В первой точке, называемой создающей точкой ожидания, свободные узлы ожидают команд диспетчера, связанных с созданием сетевых областей, а во второй, называемой освобождающей, - команд, связанных с их освобождением. В промежутке между этими точками, свободные узлы выполняют код, не связанный с созданием или освобождением сетей, определенных в исходном mpC-блоке, а именно, участвуют в тотальных вычислениях и/или в создании и освобождении сетей, определенных во вложенных mpC-блоках. Первый оператор
13 исходного mpC-блока, требующий участия в его выполнении свободных узлов, называется оператором разрыва точки ожидания. Таким образом, в общем случае целевой блок имеет следующий вид:
метка общей точки ожидания> 0
if(!MPC_Is_busy()) { целевой код, выполняемый свободными узлами для создания и освобождения сетевых областей для сетей, определенных в исходном mpC-блоке } if(MPC_Is_busy()) { целевой код, выполняемый занятыми узлами для создания и освобождения областей для сетей и подсетей, определенных в исходном mpC-блоке, а также целевой код для операторов исходного mpC-блока } эпилог общей точки ожидания
{ объявления, соответствующие объявлениям переменных в исходном mpC-блоке { if(!MPC_Is_busy()) { целевой код, выполняемый свободными узлами для создания сетевых областей для сетей, определенных в исходном mpC-блоке } if(MPC_Is_busy()) { целевой код, выполняемый занятыми узлами для создания областей для сетей и подсетей, определенных в исходном mpC-блоке, а также целевой код для операторов исходного mpC-блока, предшествующих оператору разрыва точки ожидания } эпилог создающей точки ожидания } целевой код для операторов исходного mpC-блока, начинающихся с оператора разрыва точки ожидания { целевой код, выполняемый занятыми узлами для освобождения сетевых областей для сетей и подсетей, определенных в исходном mpC-блоке метка освобождающей точки ожидания: if(!MPC_Is_busy()) { целевой код, выполняемый свободными узлами для освобождения сетевых областей для сетей, определенных в исходном mpC-блоке } эпилог освобождающей точки ожидания }
}
Если же в исходном mpC-блоке нет оператора разрыва точки ожидания, то есть, если внутри него (и во вложенных в него блоках) нет тотальных операций и нет вложенных блоков, в которых бы были определения сетей, то в целевом блоке удается совместить создающую и освобождающую точки ожидания, слив их в одну общую точку ожидания. В этом случае целевой блок имеет следующий вид: { объявления, соответствующие объявлениям переменных в исходном mpC-блоке { пролог общей точки ожидания
2:
} }
Для того чтобы во время создания сетевой области все вовлеченные узлы выполняли код, расположенный в одном файле, компилятор помещает в эпилог точки ожидания глобальный барьер. Согласованное прибытие узлов в эпилоге точки ожидания обеспечивается следующим сценарием: • хост убеждается, что все другие занятые узлы, которые могли послать запрос на создание или освобождение, ожидаемый в точке ожидания, уже достигли эпилог; • после этого хост посылает диспетчеру сообщение о том, что больше не будет запросов на создание или освобождение, ожидаемых в точке ожидания, и достигает эпилог; • после получения этого сообщения диспетчер посылает всем свободным узлам команду покинуть точку ожидания; • после получения этой команды все свободные узлы выходят из функции ожидания и достигают эпилог. 3.3 Алгоритм отображения Выше мы отмечали, что для создание сетевой области диспетчер выбирает свободные узлы, наиболее подходящие для создаваемой области. В данном разделе объясняется как диспетчер осуществляет этот выбор. Для каждого сетевого типа в исходной mpC программе компилятор генерирует 6 топологических функций, которые используются во время выполнения программы для вычисления различной топологической информации о сетевом объекте данного типа. Первая функция возвращает общее число узлов в сетевом объекте. Так как система поддержки времени выполнения использует линейную нумерацию узлов от 0 до n1, где n - общее число узлов, то вторая и третья функции преобразуют координаты узлов в
14 линейный номер и наоборот. Четвертая функция возвращает линейный номер родительского узла. Пятая функция возвращает относительную производительность указанного узла. И, наконец, шестая функция возвращает длину направленного линка, соединяющего указанную пару узлов. Когда диспетчер отображает виртуальные процессоры создаваемой сети во множество свободных узлов, он, прежде всего, вызывает соответствующие топологические функции для вычисления относительных производительностей виртуальных процессоров создаваемой сети, а также длины линков между ними. Относительная производительность виртуального процессора в создаваемой сети представляется положительным вещественным числом, нормированным относительно родительского виртуального процессора (относительная производительность которого в создаваемой сети полагается равной 1). Затем диспетчер вычисляет абсолютную производительность каждого виртуального процессора создаваемой сети, умножая его относительную производительность на абсолютную производительность родительского виртуального процессора. С другой стороны, диспетчер хранит карту вычислительного пространства, отражающую его топологические свойства. Начальное состояние этой карты формируется во время инициализации диспетчера и содержит следующую информацию: • число физических вычислительных узлов, составляющих вычислительную машину с распределенной памятью, и их производительности; • число узлов вычислительного пространства (процессов), связанных с каждым из физических вычислительных узлов; • для каждой пары физических узлов время инициализации обмена сообщениями и время передачи одного байта; • для каждого физического узла время инициализации обмена сообщениями и время передачи одного байта между парой процессов, выполняющихся на этом физическом узле. В целом, производительность физического вычислительного узла характеризуется двумя атрибутами. Первый атрибут задает скорость выполнения одного процесса на данном физическом вычислительном узле, а второй задает максимальное число невзаимодействующих процессов, которые можгут выполняться одновременно на данном физическом вычислительном узле без потери в скорости (то есть задает масштабируемость физического вычислительного узла). Например, если в качестве физического вычислительного узла используется мультипроцессор, то значение второго атрибута для него будет равно числу
процессоров. В настоящее время процедура выбора узлов вычислительного пространства для размещения на них виртуальных процессоров создаваемой сети основывается на следующей простейшей схеме. Диспетчер приписывает вес, являющийся положительным вещественным числом, каждому виртуальному процессору размещаемой сети таким образом, что: • чем мощнее виртуальный процессор, тем больший вес он получает; • чем короче линки, выходящие из виртуального процессора, тем больший вес он получает. Эти веса нормализуются таким образом, чтобы вес виртуального хост-процессора был равен 1. Аналогично, диспетчер модифицирует карту вычислительного пространства таким образом, чтобы каждый физический вычислительный узел получил вес, являющийся положительным вещественным числом, характеризующим его вычислительную и коммуникационную мощность при выполнении одного процесса. Диспетчер выбирает свободные узлы вычислительного пространства для размещения на них виртуальных процессоров последовательно, начиная с виртуального процессора, имеющего наибольший вес. Он старается выбрать наиболее мощный свободный узел для этого виртуального процессора. Для этого диспетчер оценивает мощность свободного узла для каждого физического вычислительного узла следующим образом. Пусть w - это вес физического вычислительного узла P, а N - его масштабируемость. Пусть множество H несвободных узлов, связанных с P, разбито на N подмножеств h1,...,hN; vij - вес виртуального процессора, размещенного в данный момент на jом узле множества hi;. Тогда оценка мощности свободного узла, связанного с P, вычисляется по формуле
Таким образом, диспетчер выбирает один из свободных узлов того физического вычислительного узла, для которого эта оценка оказывается максимальной, для размещения на нем очередного виртуального процессора (максимального по мощности из еще не размещенных), и добавляет этот узел к подмножеству hk множества занятых узлов соответствующего вычислительного узла, где значение k определяется из следующего соотношения:
15 Описанная процедура оказывается достаточно хорошей для сетей рабочих станций и персональных компьютеров и обеспечивает оптимальное размещение виртуальных процессоров сети, если в точности один узел вычислительного пространства связан с каждым из физических процессоров.
4. Оценка производительности Как было показано выше, язык mpC позволяет программисту определить абстрактную неоднородную сеть, наиболее подходящую для выполнения соответствующего параллельного алгоритма, и система программирования языка mpC обеспечивает отображение абстрактной сети на реально существующую. Отображение осуществляется во время выполнения и основывается на информации об относительной производительности процессоров и линий связи реальной сети. Эффективность использования потенциала производительности существующей сети параллельной программой напрямую зависит от качества этого отображения, которое в свою очередь зависит от точности оценки производительности процессоров и сетевого оборудования. Первоначально поддерживался только один способ оценки производительности процессоров и оборудования. Оценка производилась путем выполнения некоторой специальной оценочной программы и являлась частью выполнения одной из команд пользовательского интерфейса, внешнего по отношению к языку mpC. Основная слабость такого механизма заключается в использовании статической интегральной оценки производительности оборудования. Эта оценка, используемая при создании сетей, определенных внутри программы, не зависит от кода программы и является постоянной во время ее выполнения. Однако, как правило, параллельный код, выполняемый на каждой сети, существенно отличается от смеси команд в оценочной программе. Это различие не очень важно при оценке производительности микропроцессоров одинаковой архитектуры, но для микропроцессоров различной архитектуры оценки производительности, полученные с помощью различной смеси команд, могут различаться очень существенно. Как результат, в каждом конкретном случае создания сети используемая оценка становится достаточно приблизительной, что приводит к недостаточной балансировке загрузки процессоров и, как следствие, к снижению эффективности программы. Мы исследовали 4 подхода к улучшению точности оценки производительности процессоров. Первый подход заключался в
классификации mpC приложений и использовании отдельной оценочной программы для каждого класса приложений. Этот подход был отвергнут, так как эксперименты показали, что производительность процессоров может быть существенно разной даже для приложений одного класса. Рассмотрим два фрагмента программы на С for(k=0; k<500; k++) { for(i=k, lkk=sqrt(a[k][k]); i<500; i++) a[i][k]/=lkk; for(j=k+1; j<500; j++) for(i=j; i<500; i++) a[i][j]-=a[i][k]*a[j][k]; }
и for(k=0; k<500; k++) { for(j=k, lkk=sqrt(a[k][k]); j<500; j++) a[k][j]/=lkk; for(i=k+1; j<500; i++) for(j=i; j<500; j++) a[i][j]-=a[k][j]*a[k][i] }
оба реализующие разложение Холесского для матрицы 500х500. Если использовать их в качестве оценочного кода, то первый оценивает относительную производительность SPARCstation-5 и SPARCstation-20 как 10:9, а второй - как 10:14. Заметим, что функция dpotf2 пакета LAPACK, решающая эту же проблему, оценивает их относительную производительность как 10:10. Второй подход лежал в использовании специального оценочного кода для каждого mpC приложения. В частности, рассматривалась проблема автоматической генерации оценочного кода по исходному коду приложения. Такой подход требует очень значительного усложнения системы программирования языка mpC, однако он не работает, если задача, решаемая программой, распадается на несколько подзадач, каждая из которых решается на отдельной сети. В этом случае оценка производительности процессоров получается усреднением оценок, полученных на различных параллельных частях программы, и может сильно отличаться от них, как и в первом подходе. Третий подход заключается в автоматической генерации для каждой mpC программы такого оценочного кода, который давал бы векторную оценку производительности процессоров, при котором каждая параллельная часть программы, выполняемая на отдельной сети, характеризовалась бы своей оценкой, которую бы системы программирования использовала для создания этой сети. Этот подход очень сложен в реализации и не работает в том случае, если реальная сеть, используемая для вычислений, активно используется также и для других
16 вычислений. В этом случае, с точки зрения mpC программы, реальная производительность процессора является функцией времени. Поэтому использование сколь угодно сложной статической оценки, не изменяемой во время выполнения программы, часто ведет к искажению реальной производительности процессоров и, следовательно, к замедлению программы. Поэтому для реализации в системе программирования mpC был выбран четвертый подход, который заключается во введении в язык новой конструкции, которая позволяет программисту обновить во время выполнения программы оценку производительности процессоров с помощью наиболее подходящего (с его точки зрения) оценочного кода. Таким образом, для наиболее точной оценки производительности процессоров в языке mpC был введен оператор recon benchmark
Здесь benchmark либо пустой оператор состоящий только из точки с запятой, либо оператор общего вида, распределенный по всему вычислительному пространству, который определяет выполнение одинакового кода на всех виртуальных процессорах и не задает коммуникаций между ними. С помощью этого предложения обновляется информация об относительной производительности процессоров сети, используемая системой программирования mpC. Если benchmark является пустым оператором, то используется стандартный оценочный код, в противном случае в качестве оценочного кода используется код, указанный пользователем в benchmark. Кроме того, в библиотеке стандартных функций mpC есть несколько функций, которые позволяют получить текущую оценку производительности процессоров и явно задать эту оценку (без выполнения оценочного кода). Оператор recon и соответствующие библиотечные функции достаточно просты как в использовании, так и в реализации. Для демонстрации его использования рассмотрим следующую подпрограмму /*1 */ #define N 100 /*2 */ nettype Grid(P,Q) { /*3 */ coord I=P, J=Q; /*4 */ }; /*5 */ int [net Grid(p,q) v] mpC2Cblacs_gridinit(int*, char*); /*6 */ void [*]Cholesky(repl int P, repl int Q) { /*7 */ { /*8 */ int n=N,info; /*9 */ double a[N][N]; /*10*/ init(a); /*11*/ recon dpotf2_("U",&n,a,&n,&info); /*12*/ } /*13*/ {
/*14*/ net Grid(P,Q) w; /*15*/ [w]: { /*16*/ int ConTxt; /*17*/ ([(P,Q)w])mpC2Cblacs_gridinit(&ConTxt,"R "); /*18*/ pdlltdriver1_(&ConTxt); /*19*/ mpC2Cblacs_gridexit(ConTxt); /*20*/ } /*21*/ } /*22*/ }
реализующую разложение Холесского квадратной матрицы. В ней неоднородное распределение процессов, участвующих в вычислениях, по процессорам выполняется средствами mpC, а собственно параллельное разложение Холесского выполняется средствами пакета ScaLAPACK [10]. Оператор recon, определенный в строке 11, определяет производительности реальных процессоров с помощью разложения Холлеского подпрограммой пакета LAPACK dpotrf. Код этой подпрограммы является хорошим приближением для кода, который будет выполняться на каждом из узлов. Он обновляет во время выполнения информацию о производительности процессоров с помощью выполнения указанных вычислений (вызов функции dpotrf2) в качестве оценочного кода. Сеть w, выполняющая соответствующие параллельные вычисления, определена в строке 14 (ее тип определен в строках 2-4). Она состоит из PxQ виртуальных процессоров по умолчанию одинаковой производительности. Ее родитель виртуальный хост-процессор имеет по умолчанию координаты I=0, J=0. Во время выполнения это определение сети w приводит к такому отображению ее виртуальных процессоров на процессы выполняющейся параллельной программы, что число процессов, участвующих в вычислениях на каждом реальном процессоре, пропорционально его производительности, только что оцененной во время выполнения. Немного модифицированный тестовый драйвер пакета ScaLAPACK для разложения Холесского вызывается на сети w (строки 15-20). Этот драйвер читает из файла параметры задачи (размеры матрицы и блоков), формирует тестовую матрицу и проводит ее разложение. В mpC есть три вида функций: базовые, сетевые и узловые. Базовые функции вызываются и выполняются на всем вычислительном пространстве. Только в них могут создаваться сети. Примером базовой функции является функция Cholesky. Это определяется конструкцией [*] в строке 6, помещенным непосредственно перед именем функции.
17 Сетевая функция вызывается и выполняется на сети. Функция mpC2Cblacs_gridinit, определенная в строке 5, является примером сетевой функции. Она имеет три специальных формальных параметра: v, p, q. Так называемый сетевой формальный параметр v соответствует сети, на которой функция выполняется. Специальные формальные параметры p и q рассматриваются как целые переменные, размазанные по сети v. Они являются параметрами сетевого типа Grid(p,q) сети v. В строке 17 эта функция вызывается с сетью w и параметрами ее типа P и Q как аргументами, соответствующими описанным выше специальным формальным параметрам. Узловая функция может быть выполнена на любом одном виртуальном процессоре. В mpC функции языка С рассматриваются как узловые. Если переменная определена без специального определителя распределения, то в базовой функции она рассматривается распределенной по всему вычислительному пространству, а в сетевой функции по соответствующей сети. Определитель распределения [w] в строке 15 задает сеть, выполняющую составной оператор в строках 15-20.
5. Опыт использования mpC Первая реализация системы программирования mpC появилась в конце 1996 года. Уже более двух лет она свободно доступна в Internet (по адресу (http://www.isptas.ru/ mpc). За это время было проведено более 400 инсталляций системы программирования mpC во многих странах мира и ряд организаций использует ее, в основном, для проведения научных расчетов на сетях рабочих станций и ПК. mpC используется для умножения матриц, решения проблемы N тел, решения задач линейной алгебры (LU разложение, разложение Холесского и т.д.), численного интегрирования, моделирования добычи нефти, расчетов прочности строительных конструкций и многих других. Опыт использования показал, что mpC позволяет разрабатывать переносимые модульные параллельные программы, значительно ускоряющие решение как регулярных, так и нерегулярных задач на неоднородных сетях. Кроме того, mpC позволяет решать нерегулярные задачи на однородных сетях гораздо быстрее, чем традиционные средства. В этом параграфе представлены несколько типичных приложений, написанных на mpC. 5.1 Нерегулярные приложения, реализованные на mpC Рассмотрим в качестве примера нерегулярной задачи задачу моделирования эволюции системы звезд в галактике (или некоторого множества
галактик) под воздействием гравитационного притяжения. Пусть моделируемая система состоит из некоторого числа больших групп тел. Известно, что поскольку сила взаимодействия между телами быстро уменьшается с расстоянием, то воздействие большой группы тел может быть приближено воздействием одного эквивалентного тела, если эта группа тел находится достаточно далеко от точки, в которой вычисляется ее воздействие. Пусть это предположение выполняется в нашем случае, то есть пусть моделируемые группы тел находятся достаточно далеко друг от друга. В этом случае мы можем естественным образом распараллелить задачу, а наша моделирующая mpC программа будет использовать несколько виртуальных процессоров, каждый из которых будет заниматься обновлением данных, характеризующих одну группу тел. Каждый виртуальный процессор должен хранить атрибуты всех тел, образующих соответствующую группу, а также массы и центры тяжести остальных групп. Каждое тело представляется своими координатами, вектором скорости и массой. Наконец, пусть как число групп, так и количество тел в каждой из групп становятся известны только в период выполнения программы. mpC программа для решения этой задачи реализует следующую схему: Инициализировать галактику на виртуальном хост-процессоре Создать сеть для дальнейших вычислений и обменов данными Разослать группы тел по виртуальным процессорам сети Вычислить (параллельно) массы групп Обменяться массами групп между виртуальными процессорами while(1) { Визуализировать галактику на виртуальном хост-процессоре Вычислить (параллельно) центры масс групп Обменяться центрами масс между виртуальными процессорами Параллельно обновить атрибуты групп Собрать группы на виртуальном хост-процессоре }
Соответствующий следующим образом:
mpC
код
выглядит
#define MaxGs 30 /* Максимальное число групп */ #define MaxBs 600 /* Максимальное число тел в группе */ typedef double Triplet[3]; typedef struct {Triplet pos; Triplet v; double m;} Body;
18 int [host]M; /* Число групп */ int [host]N[MaxGs]; /* Массив количества тел в группах */ repl dM, dN[MaxGs]; double [host]t; /* Галактические часы */ /* Массив атрибутов тел галактики*/ Body (*[host]Galaxy[MaxGs])[MaxBs]; nettype GalaxyNet(m, n[m]) { coord I=m; node { I>=0: n[I]*n[I];}; }; void [host]Input(), UpdateGroup()б [host]VisualizeGalaxy(); void [*]Nbody(char *[host]infile) { Input(infile); /* Инициализация Galaxy, M и N */ dM=M; /* Рассылка числа групп */ /* Рассылка массива, содержащего числа тел в группах */ dN[]=N[]; { /* Создание сети g */ net GalaxyNet(dM,dN) g; int [g]myN, [g]mycoord; Body [g]Group[MaxBs]; Triplet [g]Centers[MaxGs]; double [g]Masses[MaxGs]; repl [g]i; void [net GalaxyNet(m, n[m])]Mint(double (*)[MaxGs]); void [net GalaxyNet(m, n[m])]Cint(Triplet (*)[MaxGs]); mycoord = I coordof body_count; myN = dN[mycoord]; for(i=0; i<[g]dM; i++) /* Рассылка групп */ [g:I==i]Group[] = (*Galaxy[i])[]; for(i=0; i<myN; i++) Masses[mycoord]+=Group[i].m; ([([g]dM,[g]dN)g])Mint(Masses); while(1) { VisualizeGalaxy(); Centers[mycoord][]=0.0; for(i=0; i<myN; i++) Centers[mycoord][] += (Group[i].m/Masses[mycoord])*(Group[i].p os)[]; ([([g]dM,[g]dN)g])Cint(Centers); ([g]UpdateGroup)(Centers, Masses, Group, [g]dM); for(i=0; i<[g]dM; i++) /* Сбор групп */ (*Galaxy[i])[]=[g:I==i]Group[]; } } } void [net GalaxyNet(m,n[m]) p] Mint(double (*Masses)[MaxGs]) { double MassOfMyGroup; repl i, j; MassOfMyGroup=(*Masses)[I coordof i]; for(i=0; i<m; i++)
for(j=0; j<m; j++) [p:I==i](*Masses)[j] = [p:I==j]MassOfMyGroup; } void [net GalaxyNet(m,n[m]) p] Cint(Triplet (*Centers)[MaxGs]) { Triplet MyCenter; repl i, j; MyCenter[] = (*Centers)[I coordof i][]; for(i=0; i<m; i++) for(j=0; j<m; j++) [p:I==i](*Centers)[j][] = [p:I==j]MyCenter[]; }
Этот код содержит следующие внешние определения: 1. переменных M, t, и массивов N, Galaxy, принадлежащих виртуальному хостпроцесору; 2. переменной dM и массива dN, размазанных по всему вычислительному пространству; 3. сетевого типа Galaxynet; 4. базовой функции Nbody с одним формальным параметром infile, принадлежащим виртуальному хост-процессору; 5. сетевых функций Mint и Cint. В общем случае, сетевая функция вызывается и выполняется на некоторой сети или подсети, и ее аргументы и возвращаемое значение, если таковые имеются, также распределены по этой же сети или подсети. Заголовок определения сетевой функции либо специфицирует видимый в файле идентификатор статической сети или подсети, либо объявляет идентификатор сети, являющейся специальным формальным параметром функции. В первом случае функция может вызываться только на специфицированной сети или подсети, а во втором - на любой сети или подсети подходящего вида. В любом случае, никакие другие сети, кроме указанной в заголовке определения, в теле сетевой функции создаваться или использоваться не могут. В теле функции могут создаваться только объекты данных, размещенные в связанной с ней сети или подсети, кроме которых могут использоваться и компоненты внешних объектов данных, лежащие в этой области вычислительного пространства. В отличие от базовых функций, сетевые функции (также как и узловые) могут вызываться параллельно. В коде определяются узловые функции Input и VisualizeGalaxy, связанные с виртуальным хост-процессором, и узловая функция UpdateGroup. Автоматическая сеть g, осуществляющая большую часть вычислений и коммуникаций, определена таким образом, что она состоит из M виртуальных процессоров, относительная
19 производительность которых характеризуется квадратом числа тел в группе, которую он должен обсчитывать. Таким образом, более мощный виртуальный процессор будет обсчитывать большую группу тел. Система программирования mpC, основываясь на этой информации, отобразит виртуальные процессоры, образующие сеть g, в процессы, образующие вычислительное пространство, наиболее подходящим образом. Так как это производится во время выполнения программы, то нет необходимости перетранслировать эту mpC программу при переносе ее на другую сеть компьютеров. Вызов ([g]UpdateGroup)(...) вызывает параллельное выполнение узловой функции UpdateGroup на каждом виртуальном процессоре сети g. Это означает, что имя функции UpdateGroup преобразуется в указатель на функцию, распределенный по всему вычислительному пространству, и оператор [g] вырезает из этого указателя, распределенного по всему вычислительному пространству, указатель, распределенный по сети g. Таким образом значением выражения [g]UpdateGroup является указатель на функцию, распределенный по g, и выражение ([g]UpdateGroup)(...) обозначает распределенный вызов множества нераспределенных функций. Сетевые функции Mint и Cint имеют три специальных формальных параметра. Сетевой параметр p обозначает сеть, на которой выполняется функция. Параметр m рассматривается как целая переменная, размазанная по p. Параметр n рассматривается как указатель на начальный элемент массива неизменяемых целых, размазанных по p. Фактические аргументы, соответствующие описанным формальным параметрам, задаются с помощью синтаксической конструкции ([([g]dM,[g]dN)g]), размещенной слева от имени вызываемой функции в операторе вызова в функции Nbody. Время выполнения mpC программы сравнивалось с ее тщательно написанным MPI аналогом. В качестве сети компьютеров использовались три рабочих станции SPARCstation 5(gamma), SPARCclassic(omega) и SPARCstation 20(alpha), соединенные 10Mbits Ethernet. Кроме этих трех, в нашем сегменте локальной сети было еще около 23 рабочих станции. В качестве коммуникационной платформы использовался LAM MPI [12] версия 5.2. Вычислительное пространство системы программирования mpC состояло из 15 процессов - по 5 на каждой рабочей станции. Диспетчер выполнялся на gamma и использовал следующие
относительные производительности, полученные автоматически при создании виртуальной параллельной машины: 1150(gamma), 331(omega) и 1662(alpha). Программа на MPI была написана таким образом, чтобы минимизировать накладные расходы на коммуникации. Во всех экспериментах рассматривались 9 групп тел. Три процесса MPI программы выполнялись на gamma, один на omega и пять на alpha. Такое отображение является оптимальным, если число тел во всех группах одинаково. Было проведено два эксперимента. Первый эксперимент сравнивал mpC и MPI программы для однородных входных данных, когда число тел во всех группах одинаково. Фактически, он показывал сколько мы платим за использование mpC вместо MPI. Оказалось, что время выполнения MPI программы составляет примерно 95% от времени выполнения mpC программы. То есть, в этом случае мы теряем только около 5% от производительности. Второй эксперимент сравнивал эти программы для неоднородных исходных данных. Группы состояли из 10, 10, 10, 100, 100, 100, 600, 600, 600 тел. Время выполнения mpC программы не зависит от порядка чисел. Во всех случаях диспетчер отображает: • на gamma, 4 процесса для виртуальных процессоров сети g, обсчитывающих две группы из 10 тел, одну группу их 100 тел и одну группу из 600 тел; • на omega, 3 процесса для виртуальных процессоров сети g, обсчитывающих одну группу из 10 тел, две группы из 100 тел; • на alpha, 2 процесса для виртуальных процессоров сети g, обсчитывающих две группы из 600 тел. Время моделирования 15 часов эволюции галактики mpC программой составляет 94 сек. Время выполнения MPI программы существенно зависит от порядка числа тел в группах и меняется от 88 сек до 391 сек при моделировании 15 часов эволюции галактики. Рис. 1 показывает отношение времен выполнения MPI и mpC программ для различных перестановок этих чисел. Все возможные перестановки могут быть разбиты на 24 непересекающихся подмножества одинаковой мощности таким образом, что две перестановки принадлежат одному подмножеству, если время их выполнения совпадает. Пусть эти подмножества пронумерованы таким образом, что подмножество с большим номером соответствует перестановкам с большим временем выполнения MPI программы. На рис. 1 каждое такое подмножество представлено столбцом, высота которого эквивалентна
20 соответствующему отношению времен tMPI /
tmpC.
Рис. 1. Ускорение, полученное для различных сочетаний числа тел в группах. Видно, что почти для всех исходных данных время выполнения MPI программы превышает (и часто, значительно) время выполнения mpC программы. 5.2 Регулярные приложения, реализованные на mpC Отличительной особенностью нерегулярной задачи является то, что она естественным образом разбивается на сравнительно небольшое число разных по объему вычислений подзадач. Это естественное разбиение, в свою очередь, приводит к некоторому естественному параллелизму при решении задачи, когда вся программа представляет собой небольшое число параллельных взаимодействующих процессов, каждый из которых решает свою подзадачу. Примером нерегулярной задачи служит рассмотренная в разделе 5.1 задача моделирования эволюции галактики. Регулярная задача отличается тем, что она естественным образом разбивается на сравнительно большое число одинаковых по объему вычислений небольших однородных задач. Это разбиение приводит к такому естественному параллелизму при решении регулярной задачи, при котором вся программа разбивается на большое число небольших одинаковых программ, выполняющихся параллельно и взаимодействующих через обмен данными. Примером регулярной задачи является рассмотренная в разд. 2 задача умножения плотных матриц. Основная идея эффективного решения регулярной задачи на неоднородной вычислительной системе состоит в ее сведении к нерегулярной задаче, структура которой определяется топологией вычислительной системы, на которой решается задача, а не естественной топологией задачи. Это достигается склеиванием небольших, одинаковых по объему вычислений однородных подзадач в более
крупные подзадачи, общее число которых не превышает числа доступных физических процессоров, а объемы вычислений пропорциональны мощностям этих процессоров. Поскольку mpC позволяет определять топологию исполняющей вычислительной системы в период выполнения программы, то соответствующая программа может быть написана таким образом, чтобы выполняться эффективно на любой целевой неоднородной вычислительной сети, не требуя изменений исходного кода программы и даже ее перекомпиляции. В этом подразделе представлен пример решения сложной прикладной регулярной задачи - моделирование процесса нефтедобычи - на неоднородных вычислительных сетях, а более точно, опыт использования mpC для переноса соответствующего приложения, написанного на Фортране 77 с использованием PVM (около 3000 строк исходного кода), с суперкомпьютера Parsytec PowerXplorer на сеть неоднородных рабочих станций. Процесс нефтедобычи при заводнении моделировался следующей системой дифференциальных уравнений [12]:
где
Задаются начальные нефтяном пласте)
условия
(во
всем
Здесь Sw - водонасыщенность, So нефтенасыщенность, S связанная водонасыщенность, S критическая водонасыщенность, uw и uo - скорости фильтрации воды и нефти соответственно, m - коэффициент пористости, k - абсолютная проницаемость пористой среды, kw(Sw) коэффициент относительной фазовой проницаемости воды, ko(Sw) - коэффициент относительной фазовой проницаемости нефти (относительные фазовые проницаемости являются экспериментально измеряемыми функциями насыщенности вытесняющей фазы), Fw(Sw) - функция БаклеяЛеверетта для вытесняющей фазы, μw и μo коэффициенты динамической вязкости воды и нефти, q (различают q-и q+ - объемные источники/стоки жидкости; q- - объем жидкости, извлекаемой в единицу времени на скважине добычи, q+ - объем воды, закачиваемой в
21 единицу времени на скважине накачки, вне скважин q=0), qw источники/стоки водонасыщенности, qo источники/стоки нефтенасыщенности, t - время, P - давление в пласте (одинаковое для обеих фаз, поскольку капиллярные силы не учитываются). Уравнения (1)-(2) моделируют фильтрацию двухфазной жидкости, состоящей из нефти и воды, сквозь пористую среду в водонапорном режиме. Уравнение (1) - это уравнение переноса для водонасыщенности, а уравнение (2) - это уравнение диффузии (эллиптического типа) для давления в пласте. Решениями этой системы являются водонасыщенность Sw (фракция воды в двухфазной жидкости) и давление P в пласте (одинаковое для обеих фаз, поскольку капиллярные силы не учитываются). Эти уравнения включают коэффициенты для характеристики среды: коэффициент пористости m, абсолютную проницаемость пористой среды k, коэффициенты относительной фазовой проницаемости воды kw(Sw) и нефти ko(Sw), коэффициенты динамической вязкости воды μw и нефти μo, объемные источники/стоки жидкости q, критическая и связанная водонасыщенности S_ и S , а также существенно нелинейная функция Баклея-Леверетта. Численное решение искалось в некоторой области симметрии, выделенной из неограниченного и однородного нефтяного пласта, на границах которой ставились естественные условия отсутствия потоков (6). Численный алгоритм основывался на полностью явных методах решения уравнений (1)-(2), а именно, уравнение (1) решалось с помощью итерационного метода секущих, а для решения эллиптического уравнения (2) использовался итерационный (α-β)-алгоритм [12]. С целью в ускорения сходимости (α-β)-алгоритма уравнения для некоторых прогоночных коэффициентов был включен параметр релаксации. Параллельная реализация алгоритма для выполнения на однородных мультипроцессорных системах с распределенной памятью основывалась на декомпозиции расчетной области (параллелизм данных): область разбивалась на подобласти одинакового размера вдоль Y-координаты, обсчитываемые параллельно разными процессорами исполняющего суперкомпьютера. Такое разбиение оказалось эффективнее как разбиения вдоль X-координаты, так и разбиения по двум направлениям сразу, поскольку обеспечивает меньшую интенсивность обменов данными между процессорами при выполнении параллельного (α-β)-алгоритма. В каждой подобласти уравнения (1)-(2) решались следующим образом. Для каждого временного
слоя, водонасыщенность получается решением уравнения (1) с использованием значений давления, полученных для предыдущего временного слоя. Затем, с использованием найденной таким образом водонасыщенность, рассчитывается новое давление для текущего временного слоя путем решения уравнения (2). Потом эта процедура повторяется для следующего временного слоя. Основная трудность этого параллельного алгоритма заключалась в определении оптимального параметра релаксации омега для параллельного (α-β)-алгоритма, поскольку этот параметр меняется при разбиении расчетной области на разное число подобластей одинакового размера. Использование неоптимальных параметров релаксации приводило к значительному росту числа итераций или даже к потере сходимости параллельного (αβ)-алгоритма. Многочисленные эксперименты позволили найти оптимальное значение параметра релаксации для различного числа подобластей. Описанный алгоритм был реализован на языке Fortran 77 с использованием коммуникационной библиотеки PVM и продемонстрировал хорошие масштабируемость, ускорение и эффективность распараллеливания при выполнении на параллельном компьютере Parsytec PowerXplorer многопроцессорной вычислительной системе, использующей процессоры PowerPC 601 в качестве вычислительных узлов и транспьютеры T800 в качестве коммуникационных узлов (один T800 обеспечивает передачу данных со скоростью 20 Мбит/с по 4 двунаправленным линкам). В табл. 1 представлены результаты, полученные при расчете первого временного слоя. Здесь эффективность распараллеливания определяется как (Sreal/Sideal) ×100%, где Sreal - это фактическое ускорение, достигнутое параллельной программой, а Sideal - идеальное ускорение, которое могло бы быть достигнуто при решении задачи на данной параллельной вычислительной системе. Последнее вычисляется как отношение суммы производительностей процессоров системы к производительности базового процессора. Все ускорения вычисляются относительно времени выполнения исходной последовательной программы на базовом процессоре. Заметим, что эффективность распараллеливания тем выше, чем быстрее коммуникационные линки и слабее процессоры. Вообще говоря, предполагалось, что параллельная программа моделирования процесса нефтедобычи должна быть частью переносимой программной системы, способной работать на только на суперкомпьютерах, но и на локальных сетях неоднородных компьютеров и обеспечивающей автоматизированное рабочее
22 место эксперта в области нефтедобычи. Поэтому потребовалась переносимая версия программы, эффективно решающая задачу моделирования нефтедобычи на сетях компьютеров. Табл. 1. Производительность параллельной Fortran-программы, реализующей неявный алгоритм решения задачи нефтедобычи, при расчетах на многопроцессорной системе Parsytec PowerXplorer в среде программирования PARIX Число проц.
ω
1 2 4 8
1.197 1.2009 1.208 1.22175
Число ЭффективВремя Ускорение итераций ность 205 211 214 226
120 64 38 26
1 1.875 3.158 4.615
100% 94% 79% 58%
Табл 2. Относительная производительность рабочих станций Номер рабочей станции Производ тельность
1
2
3-4
5-7
8-9
1150
575
460
325
170
В качестве первого шага эта параллельная Fortran/PVM-программа безо всяких изменений была перенесена на локальную сеть, основанную на 10 Mbits Ethernet и состоящую из 9 однопроцессорных рабочих станций SUN. Для сравнения с производительностью процессоров PowerPC-601, на которых базируется Parsytec PowerXplorer, отметим, что самая "слабая" рабочая станция используемой сети (SPARCclassic) выполняет последовательную программу моделирования процессов нефтедобычи немного медленнее, чем PowerPC601, а самая мощная (UltraSPARC-1) выполняет эту программу более чем в 6 раз быстрее. Относительные производительности рабочих станций при решении задачи нефтедобычи приведены в табл. 2 (станциям присвоены номера, используемые в последующих таблицах). Табл. 3. Производительность параллельной Fortran/PVM - программы, моделирующей процессы нефтедобычи, при расчетах на подсетях рабочих станций Подсеть Число Время Идеал. Реал. (номера ω итер. (сек) ускор ускор. станций) {2,5} 1.2009 211 46 1.57 0.88 {5,6} 1.2009 211 47 2.0 1.52 {2,5 -7} 1.208 214 36 2.7 1.13 {2-7} 1.21485 216 32 4.3 1.27 {2,3,5-8} 1.21485 216 47 3.8 0.87 {1-8} 1.22175 226 46 3.3 0.41
Эффективность 0.56 0.76 0.42 0.30 0.23 0.12
В таблице 3 представлены результаты расчетов одного временного слоя с помощью этой Fortran/PVM-программы на различных подсетях этой неоднородной сети, состоящих из двух, четырех, шести и восьми рабочих станций. Эти результаты включают значения параметра релаксации и соответствующие количества βитераций, время расчета, идеальное и реальное ускорение, а также эффективность использования подсети. Здесь ускорение вычисляется относительно времени выполнения последовательной программы на самой мощной рабочей станции подсети (время выполнения последовательной программы на различных рабочих станциях приведено в таблице 4). Заметное падение эффективности распараллеливания по сравнению с Parsytec PowerXplorer объясняется тремя причинами более медленными коммуникационными каналами, более быстрыми процессорами и несбалансированной загрузкой процессоров с различной производительностью. В то время как первые две причины неустранимы, последнюю можно преодолеть путем небольшой модификации параллельного алгоритма, реализуемого Fortran/PVMпрограммой. А именно, для оптимальной загрузки процессоров, расчетная область разбивается на подобласти разного размера, пропорциональные относительным производительностями участвующих в вычислениях процессоров. Точнее говоря, в результате такой неравномерной декомпозиции в каждой подобласти оказывается равное число столбцов расчетной сетки, но разное число строк. Что же касается параметра релаксации, разумно предположить, что его оптимальное значение является функцией числа строк расчетной сетки, и использовать для каждой подобласти свое значение ω = ω(Nrow). Экспериментально была найдена последовательность оптимальных значений параметра релаксации для некоторых фиксированных значений Nrow по которым с использованием кусочно-линейной интерполяции определялось приближенно значение ω для любого числа строк Nrow расчетной сетки в каждой подобласти. Заметим, что такой подход обеспечил достаточно высокую скорость сходимости параллельного (α-β)-алгоритма с релаксацией (см. "Число итераций" в табл. 5). Этот модифицированный алгоритм очень непросто выразить средствами PVM в переносимой форме. Дело в том, что PVM, подобно другим библиотекам передачи сообщений или HPF, не поддерживает создание группы процессов, основываясь на таком свойстве создаваемой группы, как относительные скорости процессов. Поэтому, программа, реализующая неоднородный параллельный
23 алгоритм моделирования процесса нефтедобычи, была написана на языке mpC. Эта mpC-программа определяет во время выполнения число и относительные производительности доступных процессоров, создает группу процессов таким образом, чтобы каждый процесс выполнялся на отдельном процессоре, и распределяет данные и вычисления пропорционально относительным производительностям процессоров. Заметим, что mpC-программа не только обеспечивает новые функциональные возможности, но и позволяет более чем в 3 раза сократить исходный код (по сравнению с исходной Fortran/PVM-программой). Табл. 4. Производительность программы (последовательной), моделирующей процессы нефтедобычи, при расчетах на рабочих станциях Ultra SPARC SPARC SPARC 5 SPARC-1 20 station 4 Станция 1 2 3 4 5 6 7 Итерации 205 Время (сек) 18.7 40.7 51.2 51.2 71.4 71.4 71.4 Процессор
SPARC classic 8 9 133 133
Табл. 5. Производительность параллельной mpC-программы, моделирующей процессы нефтедобычи, при расчетах на подсетях рабочих станций Подсеть Время Число Время Реал. Ускор. Эффект. (Номера Эффект. 205 ит. Итер. (сек) ускор 205 ит. 205 ит. станций) (сек) {2,5} 324 41.6 0.98 0.63 28.2 1.44 0.92 {5,6} 225 38.8 1.84 0.92 36.4 1.96 0.98 {2,5-7} 279 26 1.57 0.58 19.7 2.07 0.77 {2-7} 245 17.9 2.27 0.54 15 2.71 0.63 {2-8} 248 20.2 2.01 0.54 17 2.39 0.64 {2-8}* 260 32.8 1.24 0.33 26.8 1.52 0.40 {2-9} 268 21 1.94 0.40 16 2.54 0.53 расчетная область была насильно поделена на равные подобласти
Разработанная mpC-программа на гетерогенных сетях компьютеров дает умеренные ускорение и эффективность распараллеливания (см. табл. 5), которые, однако, значительно выше аналогичных характеристик Fortran/PVMпрограммы табл. 3). Несмотря на увеличение числа итераций, mpC-программа позволяет сократить время вычислений за счет оптимизации обменов и, что главное, сбалансированности загрузки процессоров (ср. "время" в табл. 5 и 3). Для оценки чистого выигрыша от балансировки загрузки mpC-программа запускалась на одной и той же подсети, состоящей из рабочих станций с номерами {2,3,5,6,7,8}, дважды с автоматическим распределением данных в соответствии с относительными производительностями процессоров и с насильственным равномерным распределением
данных. В последнем случае наблюдались возрастание времени вычислений более чем в 1.5 раза и соответствующая деградация ускорения и эффективности распараллеливания (в табл. 5, помечено *). Умеренная эффективность распараллеливания mpC-программы во многом объясняется спецификой адаптации (α-β)-алгоритма с релаксацией к гетерогенным сетям. Этот алгоритм очень чутко реагирует на точность определения параметров ω, а описанная выше процедура приближенного вычисления параметров при неравномерной декомпозиции расчетной области дает удовлетворительный, но не наилучший результат. Число итераций, необходимых для сходимости параллельного алгоритма, существенно отличается от числа итераций в последовательном варианте. Поэтому интересно было измерить время, за которое на подсетях совершается 205 итераций -- то количество итераций, за которое β-процесс сходится с указанной выше точностью на одном процессоре. Соответствующие данные представлены в табл. 5, из которой следует, что если бы при распараллеливании удалось избежать возрастания числа итераций (например, за счет более точного определения параметров релаксации), на гетерогенных сетях можно было бы достичь весьма высоких ускорения и эффективности параллельной mpC-программы, моделирующей процессы нефтедобычи.
6. Другие работы в этом направлении Все известные нам программные системы для параллельного программирования на сетях имеют одно общее свойство, которое заключается в том, что при разработке параллельной программы либо программист не имеет средств для описания виртуальной параллельной системы, выполняющей программу, либо эти средства настолько бедны, что не позволяют определить эффективное распределение вычислений и коммуникаций по целевой сети. Даже топологические возможности MPI (включая MPI2 [13]) недостаточны для решения этой проблемы. Поэтому для обеспечения эффективного выполнения программы на конкретной сети пользователь должен использовать средства, внешние по отношению к языку, такие как схема загрузки или схема приложения [14]. Если пользователь знаком и с топологией целевой сети (то есть ее структурой и производительностями процессоров и линий связи), и с топологией приложения (то есть ее параллельной структурой), то с помощью конфигурационных файлов он может так отобразить процессы, составляющие программу, на процессоры сети, чтобы обеспечить ее наиболее эффективное
24 выполнение. Есть системы, которые поддерживают такое статическое отображение [15]. Однако если топология приложения определяется во время выполнения (например, зависит от исходных данных), то такой подход перестает работать. Существуют системы [16, 17], которые реализуют некоторые функции распределенной операционной системы и стараются учесть неоднородность производительности процессоров сетей компьютеров при управлении задачами с целью максимизации пропускной способности сети компьютеров как одного компьютера. В отличие от этих систем, mpC предназначен для минимизации времени выполнения отдельного параллельного приложения на сети, что и является наиболее важным для конечного пользователя.
7. Заключение Наиболее общей параллельной архитектурой является сеть компьютеров. В статье описывается язык mpC, предназначенный для эффективнопереносимого модульного параллельного программирования сетей компьютеров, и его система программирования. К наиболее важными свойствам mpC можно отнести следующие: • однажды разработанное mpC приложение будет эффективно выполняться на любой сети компьютеров без какого-либо изменения исходного текста (мы называем это свойство эффективной переносимостью); • mpC позволяет писать приложения, адаптирующиеся не только к номинальной производительности процессоров, но и перераспределяющие вычисления и коммуникации в соответствии с динамическими изменениями загрузки компьютеров сети. Более двух лет мы экспериментируем с mpC и разработали технологию его использования для высокопроизводительных вычислений на неоднородных сетях. Эта технология была успешно применена для решения следующих задач. • Эффективное использование на неоднородных сетях компьютеров традиционного параллельного программного обеспечения, перенесенного с суперкомпьютеров. Примером является интерфейс между mpC и ScaLAPACK, позволяющий использовать последний на неоднородных сетях (более детально описано в разделе 4); потребовалась примерно неделя для разработки интерфейса и несколько дней для переноса сложного ScaLAPACK приложения на неоднородные сети с помощью интерфейса.
•
Перекодирование на mpC с изменениями, обеспечивающими эффективное выполнение на неоднородной сети, суперкомпьютерных параллельных приложение. Примером является перенос приложения для моделирования добычи нефти, написанного на Фортране 77 с вызовами PVM, с суперкомпьютера Parsytec на сеть неоднородных рабочих станций (более детально описано в подразделе 5.2); на разработку соответствующего mpC приложения потребовалось около двух недель; на сети из 8 рабочих станций mpC приложение выполняется в три раза быстрее, чем его Фортран/PVM аналог на этой же сети и в два раза быстрее чем Фортран/PVM приложение на 8 процессорном сегменте суперкомпьютера Parcytec. • Распараллеливанию последовательных программ для выполнения на неоднородных сетях. Например, на языке mpC была разработана параллельная версия классической адаптивной фортранной программы численного интегрирования quanc8 [13], основанной на квадратурной формуле Ньютона-Кортеса 8-го порядка; в случае вычислительно сложных подынтегральных функций эта mpC-программа позволяет существенно ускорить вычисление определенных интегралов, используя доступные компьютеры локальной сети; отметим, что эта программа во время выполнения автоматически перераспределяет объемы вычислений, выполняемые разными компьютерами, в зависимости от их текущей загрузки; разработка программы заняла 2 дня. • Разработке оригинальных mpC-программ. Например, была разработана параллельная программа моделирования на неоднородных сетях эволюции систем тел под воздействием гравитационного притяжения (более детально описано в подразделе 5.1), которая продемонстрировала многократное ускорение по сравнению в тщательно написанной, но не учитывающей неоднородности MPIпрограммой. Мы продолжаем работать над mpC и его системой программирования. Наша работа направлена как на обеспечение высокой эффективности для широкого диапазона сетей компьютеров (включая кластеры суперкомпьютеров и глобальные сети), так и на улучшение программной модели. Библиография 1. H.El-Rewini, and T.Lewis, Introduction To Distributed Computing, Manning Publications Co., 1997. 2. Message Passing Interface Forum, MPI: A Messagepassing Interface Standard, ver. 1.1, June 1995.
25 3. A.Geist, A.Beguelin, J.Dongarra, W.Jlang, R.Manchek, V.Sunderam, PVM: Parallel Virtual Machine, Users' Guide and Tutorial for Networked Parallel Computing, MIT Press, Cambridge, MA, 1994. 4. High Performance Fortran Forum, High Performance Fortran Language Specification, version 1.1, Rice University, Houston TX, November 10, 1994. 5. C.Koelbel, "Conferences for Scientific Applications", IEEE Computational Science & Engineering, 5(3), pp.91-95, 1998. 6. S. S. Gaissaryan, and A. L. Lastovetsky, "An ANSI C Superset for Vector and Superscalar Computers and Its Retargetable Compiler", The Journal of C Language Translation, 5(3), March 1994, pp.183-198. 7. Thinking Machines Corporation, "The C* Programming Language", CM-5 Technical Summary, pp. 69-75, November 1992. 8. P. J. Hatcher, and M. J. Quinn, Data-Parallel Programming on MIMD Computers, The MIT Press, Cambridge, MA, 1991. 9. D.Arapov, A.Kalinov, A.Lastovetsky, and I.Ledovskih "Experiments with mpC: Efficient Solving Regular Problems on Heterogeneous Networks of Computers via Irregularization", Proceedings of the Fifth International Symposium on Solving Irregularly Structured Problems in Parallel (IRREGULAR'98), LNCS 1457, Berkley, CA, USA, August 9-11, 1998, pp.332-343. 10. B.Chetverushkin, N.Churbanova, A.Lastovetsky, and M.Trapeznikova, "Parallel Simulation of Oil Extraction on Heterogeneous Networks of Computers", Proceedings of the 1998 Conference on Simulation Methods and Applications (CSMA'98), the Society for Computer Simulation, November 1-3, 1998, Orlando, Florida, USA, pp. 53-59. 11. A.Kalinov, and A.Lastovetsky, "Heterogeneous Distribution of Computations While Solving Linear Algebra Problems on Networks of Heterogeneous Computers", Proceedings of the 7'th International Conference on High Performance Computing and Networking Europe (HPCN Europe'99), LNCS 1593, Springer-Verlag, April 12-14, 1999, Amsterdam, the Netherlands pp.191-200. 12. B. N. Chetverushkin, N. G. Churbanova, and M. A. Trapeznikova,"Simulation of oil production on parallel computing systems", Proceedings of Simulation MultiConference HPC'97: Grand Challenges in Computer Simulation, Ed. A.Tentner, Atlanta, USA, April 6-10, 1997, pp.122-127. 13. MPI-2: Extensions to the Message-Passing Interface, http://www.mcs.anl.gov. 14. Trollius LAM Implementation of MPI. Version 6.1, Ohio State University, 1997. 15. F.Heinze, L.Schaefers, C.Scheidler, and W.Obeloeer, "Trapper: Eliminating performance bottlenecks in a parallel embedded application", IEEE Concurrency, 5(3), pp.28-37, 1997. 16. Dome: Distributed Object Migration Environment, http://www.cs.cmu.edu/ Dome/. 17. Hector: A Heterogeneous Task Allocator, http://www.erc.msstate.edu/ russ/hpcc/.
Параллельное программирование в среде Java для систем с распределенной памятью. Объектные модели параллельного выполнения С.С. Гайсарян, М.В. Домрачев, В.Ф. Еч, О.И. Самоваров, А.И. Аветисян
1. Введение Цель настоящей работы* состоит в исследовании возможностей включения в стандартную среду языка программирования Java [1] средств, поддерживающих разработку параллельных программ в рамках модели SPMD для параллельных вычислительных систем с распределенной памятью. При этом имеется в виду два класса таких систем: • многопроцессорные параллельные компьютеры с распределенной памятью; • локальные сети рабочих станций. Многопроцессорные параллельные компьютеры с распределенной памятью обычно состоят из нескольких десятков (а иногда и сотен) процессоров (узлов), объединенных в сеть быстрыми коммутирующими устройствами. Примером такой вычислительной системы может служить компьютер FatNode фирмы SUN, содержащий 64 узла UltraSparc. Быстрые системы коммутации, применяемые для объединения компьютеров в локальную сеть, позволяют, объединяя несколько FatNode, получать системы с большим числом узлов. Локальные сети рабочих станций представляют особый класс вычислительных систем с распределенной памятью. В отличие от распределенных компьютеров, сети рабочих станций, как правило, неоднородны (т.е. содержат компьютеры различных типов и с разной производительностью), а это приводит к дополнительным накладным расходам, которые не только замедляют выполнение параллельной программы, но и влияют на такие существенные ее
*
Работа поддержана грантом РФФИ 99-01-00206
свойства, как масштабируемость. Поэтому параллельные программы, отлаженные на сети рабочих станций, вообще говоря, не будут сохранять своих свойств при переносе на параллельный компьютер. В модели SPMD (Single Program, Multiple Data) [2] параллельная программа рассматривается как набор функционально одинаковых компонент (последовательных программ). Каждая компонента выполняется независимо на отдельном процессоре параллельной вычислительной системы, обрабатывая ту часть распределенных данных, которая попала на этот процессор. Если при этом требуются данные с других процессоров, то они пересылаются по сети. Модель SPMD используется во многих современных системах параллельного программирования (см., например, [3 – 6]). Язык программирования Java, впервые опубликованный в 1995 году фирмой SUN, быстро завоевал популярность и стал одним из наиболее распространенных языков программирования. Это объясняется не только тем, что фирма SUN затратила огромные средства на внедрение Java, но и многими достоинствами языка Java и его окружения. Отметим наиболее существенные из них: 1. Полная переносимость программ – программа на языке Java работает на любой программноаппаратной платформе, поддерживающей среду Java, не требуя каких-либо модификаций или преобразований. Это свойство позволяет избежать процесса установки программы на конкретную платформу для оценочного запуска. Как следствие, при распределенном и параллельном программировании снимаются проблемы неоднородности вычислительной среды, требующие достаточно больших накладных расходов во время выполнения. 2. Простота объектной модели, реализованной в системе Java, позволяет легко разбираться в исходной программе, облегчает внесение в нее изменений и дополнений во время отладки и сопровождения, упрощает документирование программы. При этом система программирования Java отвечает всем требованиям к современным системам программирования: наличие механизма исключительных ситуаций, поддержка легковесных процессов (тредов), потоковый
27 ввод/вывод, поддержка средств сетевого программирования (библиотека сокетов), графический интерфейс пользователя, системы обеспечения безопасности при пересылке данных и байт-кода по сети и т.д. 3. Детерминированность получаемого кода – свойство языка, не позволяющее программисту написать программу, в которой возможны несанкционированные действия, такие как обращение к объектам с помощью "висячих" указателей или преобразование случайного участка памяти в экземпляр объекта в результате ошибки в адресной арифметике. Переносимость программы на Java позволяет пользователю получать исходный код (или байткод) программы и использовать его на своей платформе без каких бы то ни было доработок. Введение в среду Java возможности организации параллельных вычислений позволит разрабатывать параллельные программы, переносимые на различные параллельные платформы. Это существенно упростит распространение параллельных программ (например, через Internet). Отметим также, что средства написания параллельных программ на Java дадут возможность пользователям, ранее не имевшим доступа к параллельным вычислительным ресурсам, использовать параллельные высокопроизводительные вычислительные комплексы, доступные через Internet. Такая организация доступа к параллельным вычислительным ресурсам позволит эффективно выполнять разовые научные или инженерные расчеты, требующие большого объема вычислений, без необходимости установки специального программного обеспечения и без дополнительной компиляции исходной программы для конкретной параллельной архитектуры. Однако существуют обстоятельства, препятствующие использованию среды языка Java для разработки параллельных программ. Они связаны со следующими особенностями системы программирования Java: 1. Java – интерпретируемый язык: объектным кодом системы программирования Java является не код процессора, на котором выполняется Java-программа, а байт-код (JavaBC), язык интерпретатора Java-программ (JavaVM). Интерпретация байт-кода, естественно, требует дополнительных накладных расходов и приводит к замедлению выполнения Java-программ. Разработчики системы Java утверждают, что накладные расходы, связанные с интерпретацией, приводят к замедлению в 2 – 2,5 раза, однако на практике было выяснено, что замедление может быть и более существенным (до 10 раз). 2. В системе Java запрещены какие бы то ни было изменения и расширения. Запрещено вводить новые конструкции в язык Java и в JavaBC, запрещено менять JavaVM, запрещено использовать препроцессоры. Единственным разрешенным способом расширять язык Java является разработка новых классов и библиотек классов.
Запрещение любых способов внесения изменений в язык Java или в его интерпретатор, что дало бы возможность обойти ограничения, следует рассматривать как цену, которую необходимо платить за удобство программирование на Java, за надежность и переносимость Java-программ, за возможность их выполнения в произвольной компьютерной сети. В данной работе исследуется возможность введения параллельных средств в язык Java средствами самого языка Java, а именно с помощью библиотек интерфейсов и классов. Эти интерфейсы и классы в своей совокупности могут рассматриваться как объектная модель системы параллельного программирования. В настоящее время работы по организации параллельных вычислений на Java вызывают большой интерес среди различных групп, работающих над созданием систем параллельного программирования. Краткий обзор работ по параллельным расширениям Java содержится в разделе 2. В разделе 3 рассматриваются два способа организации параллельных вычислений в рамках модели SPMD (их можно рассматривать как конкретизацию этой модели): модель DPJ (Data Parallel Java) и модель DVM (Distributed Virtual Machine). Сравнение моделей DPJ и DVM показывает, что модель DPJ лучше учитывает особенности программирования в объектноориентированном окружении Java. В разделе 4 рассматриваются примеры параллельных программ, использующих библиотеки DPJ и JavaDVM, и анализируются способы повышения их производительности. Там же указывается адрес указанных библиотек классов на сайте Internet. За рамками статьи осталось описание библиотеки, реализующей основные функции стандарта передачи сообщений MPI [7] на языке Java. Эта библиотека дает возможность пользоваться библиотеками DPJ и DVM, не выходя за рамки среды Java, т.е. существенно упрощает доступ к этим библиотекам для пользователей системы Java.
2. Краткий обзор работ по параллельному расширению языков программирования и обоснование выбранного подхода к параллельному расширению языка Java Как было отмечено во введении, в настоящее время работы по организации параллельных вычислений на Java вызывают большой интерес среди различных групп, работающих над созданием систем параллельного программирования. Об этом можно судить по регулярным публикациям по этому вопросу в периодических изданиях и на Internet (см., например, [3]). В настоящее время применяется несколько парадигм параллельного программирования:
28 • использование низкоуровневых библиотек передачи сообщений для обычных языков программирования; • специальные указания: аннотации, прагмы, или параллельные операторы, – как правило, реализованные в виде комментариев, – которые вставляются в последовательную программу и помогают компилятору, который учитывает эти указания, сгенерировать соответствующую параллельную программу; • новые параллельные языки (в том числе расширения последовательных языков новыми конструкциями для описания параллельных вычислений). Использование низкоуровневых библиотек передачи сообщений для обычных языков программирования предполагает, что программист, используя один из стандартных последовательных языков, пишет узловые программы, запоминает, на каких узлах расположены какие данные, определяет источник и приемник данных для каждого коммуникационного акта, вызывает функции преобразования данных (если в параллельной программе используются процессоры различной архитектуры), "вручную" осуществляет балансировку вычислительной и коммуникационной нагрузки узловых программ. Оптимизация коммуникаций и отслеживание масштабируемости программы также ложится на программиста. Зачастую эти операции являются противоречивыми, например, программа, хорошо сбалансированная для четырех процессоров, нуждается в повторной балансировке для восьми процессоров, т.е. возникают проблемы, связанные с масштабированием программы. При большом количестве процессоров в параллельном компьютере написание эффективной программы становится очень сложным и трудоемким занятием. Отметим, что такой способ разработки параллельных программ поддерживался системой программирования Occam [8], разработанной в конце 80-х годов для транспьютерных сетей. Сказанное можно пояснить с помощью простого примера параллельной программы на языке C с использованием стандартной библиотеки передачи сообщений MPI (рис. 1). В примере выделяется группа из двух процессоров из вычислительного пространства и от первого ко второму передается массив целых чисел. #include "mpi.h" #define BUFLEN 512 #define GRP_SIZE 2 int main(int argc, char* argv[]) { int i, myid, numprocs, rc; int buffer[BUFLEN]; MPI_Status status; MPI_Group MPI_GROUP_WORLD, grp1; MPI_Comm newComm; int hosts[3] = {0,1,2}; MPI_Init(&argc,&argv); MPI_Comm_group(MPI_COMM_WORLD, &MPI_GROUP_WORLD); MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
If( numprocs < GRP_SIZE ) exit(1); MPI_Group_incl(MPI_GROUP_WORLD, 3, hosts, &grp1); MPI_Comm_create(MPI_COMM_WORLD, gr2, &newComm); MPI_Comm_rank(newComm, &myid); if(newComm != MPI_COMM_NULL) { if (myid == 0) { // Инициализация буфера опущена . . . MPI_Send(buffer, BUFLEN, MPI_INT, 1, 99, MPI_COMM_WORLD); } else { MPI_Recv(buffer, BUFLEN, MPI_INT, 0, 99, MPI_COMM_WORLD, &status); } MPI_Comm_free(&newComm); } MPI_Group_free(&grp1); MPI_Group_free(&MPI_GROUP_WORLD); MPI_Finalize(); }
Рис. 1. Простая параллельная программа на языке C с использованием пакета MPI для передачи данных между процессорами Как видно из примера, даже несложные действия влекут за собой большой размер получаемого кода, что способствует возникновению ошибок, причем ошибки эти достаточно трудно найти и исправить, так как необходимо одновременно следить за состоянием многих работающих программ. Кроме того, хотя большая часть библиотек, реализующих передачу сообщений, и реализована практически на всех известных платформах, сохраняются проблемы переноса программы на обычном процедурном языке с платформы на платформу. Свойства масштабируемости такой программы также меняются при переносе на другую платформу, и ее приходится заново оптимизировать и отлаживать или частично переписывать. Таким образом, программист, использующий эту парадигму, сталкивается со сложными проблемами на всех циклах разработки программы: при ее написании, отладке, оптимизации и сопровождении. Тем не менее, приходится констатировать, что в настоящее время подавляющее большинство прикладных параллельных программ разрабатывается именно таким способом. В качестве стандартных языков программирования обычно используются Fortran 77, Fortran 90, или C. Передача данных между узлами параллельного компьютера обычно реализуется с помощью библиотек PVM [9], или MPI [7]. Существуют многочисленные реализации этих библиотек, как коммерческие, так и свободно доступные (в том числе, через Internet). Вторая парадигма связана с использованием аннотаций, или прагм, добавленных в стандартный последовательный язык программирования в форме специальных комментариев. Программа, написанная на таком языке, может проходить и через стандартный последовательный компилятор с этого языка, и через специальный
29 распараллеливающий компилятор, который понимает специальные комментарии и использует информацию, содержащуюся в них, для генерации параллельной программы. Обычно аннотации содержат сведения о распределении данных по узлам параллельного компьютера. Распределение вычислений и синхронизация передачи данных осуществляются компилятором автоматически. Наиболее известным языком, реализующим рассматриваемую парадигму, является HPF (High Performance Fortran) [4].Пример, рассмотренный выше, на HPF может быть представлен следующим образом (рис. 2).
1
C$HPF PROCESSORS P(2) INTEGER A(512*2) C Инициализация A(1..512) . . . . . . . . . . . . . . . C$HPF DISTRIBUTE A(512) ON P DO 1 I=1,512 A(I+512) = A(I) CONTINUE STOP
Рис. 2. Параллельная программа с рис.1, записанная на языке HPF В приведенном примере C является признаком строки комментария, а C$HPF – признаком специального комментария, в котором задаются аннотации HPF. По информации, содержащейся в строках программы, начинающихся с символов C$HPF, компилятор HPF должен выяснить, где происходит реальная пересылка данных, и выбрать правильную стратегию их передачи (например, использовать буферизацию). При использовании HPF сбалансированность нагрузки, оптимальность коммуникаций и свойства масштабируемости программы практически целиком зависят от того, какие алгоритмы и эвристики реализованы в конкретном компиляторе и его системе поддержки. Программист практически не влияет на процесс оптимизации параллельной программы. Этим объясняется сравнительно редкое использование HPF при разработке реальных прикладных программ. Появление новой версии HPF – языка HPF-2, обеспечивающего ряд дополнительных возможностей, не увеличило популярности HPF среди разработчиков прикладных параллельных программ. Это привело к закрытию исследований по HPF и официальному признанию бесперспективности направления. Тем не менее, другие системы параллельного программирования, в которых используется подход, близкий к HPF, продолжают разрабатываться. Одной из таких работ является модель DVM, рассматриваемая в данной работе. Эта модель идеологически очень близка к модели, лежащей в основе HPF. Однако в отличие от HPF, основу системы DVM составляет не возможность более просто описывать распределение данных по сети с помощью аннотаций, а библиотеки инструментальных программ, использующие аннотации для трассировки и мониторинга параллельных программ, что помогает их отлаживать и улучшать степень их
распараллеленности (своеобразная диалоговая оптимизация). Инструментальные библиотеки системы DVM обеспечили ее практическое использование при разработке прикладных параллельных программ. Другой работой, идеологически близкой к HPF, является разработка языка и системы программирования Linda [10]. В этой системе программирования реализована модель VSM (Virtual Shared Memory). http://www.qpsf.edu.au/workshop/linda Третье решение – создать новый язык программирования с высокоуровневыми абстракциями для параллельного программирования и явными параллельными конструкциями. Примером такого языка может служить язык mpC [11], разработанный и реализованный в ИСП РАН. Рассматриваемый пример запишется на mpC следующим образом (рис. 3). #include "mpc.h" #define BUFLEN 512 nettype SimpleNet(n) { coord I=n; } void [*]main() { net SimleNet(2)n; int [n]a[BUFLEN]; [n:I==0] { /* Инициализация буфера a */ } [n:I==1]a[] = [n:I==0]a[]; }
Рис. 3. Параллельная программа с рис.1, записанная на языке mpC По этому тексту компилятор mpC автоматически сгенерирует программу на C с вызовами функций из библиотеки MPI, похожую на программу, приведенную на рис. 1. Легко видеть, что исходная программа получилась значительно проще, чем в случае непосредственного использования MPI. Среди работ, близких к mpC, можно отметить еще одно параллельное расширение C – язык Charm/Charm++ [12]. Как и mpC, Charm представляет собой систему параллельного программирования, причем Charm++ является расширением языка C++ (т.е. объектноориентированным языком параллельного программирования). К сожалению, разработчики новых языков параллельного программирования, как показывает анализ их языков, имеют весьма скромный опыт разработки оригинальных прикладных параллельных программ. Они плохо представляют, какие этапы разработки параллельной программы требуют автоматизации в первую очередь. И они совершенно игнорируют то обстоятельство, что внедрение нового языка программирования требует больших затрат, связанных с необходимостью обеспечения возможности использования в новом языковом окружении внешних библиотек и прикладных программ, разработанных в других организациях. Между тем, анализ неудачи, постигшей HPF, показал, что при разработке параллельных
30 программ прикладным программистам удобнее в явном виде задавать пересылку данных между процессорами (ведь правильная организация пересылки данных – единственная возможность обеспечить высокую скорость вычислений). Несмотря на свою громоздкость, программа, приведенная на рис. 1, понятнее для своего разработчика, чем программы на рис. 2 и 3. Это особенно важно при отладке параллельной программы и при оптимизации ее параллельных свойств. Тут уместно вспомнить, что когда основная память компьютеров была достаточно скромных размеров (например, на БЭСМ-6 было всего 6 Mb), разработчики программ решения систем алгебраических уравнений не удовлетворялись системной виртуальной памятью, а писали свои собственные системы замещения страниц, что позволяло им существенно ускорить свои программы. Таким образом, можно утверждать, что высокоуровневые универсальные модели параллельных вычислений, лежащие в основе языков параллельного программирования высокого уровня, не были приняты программистским сообществом. Следовательно, основные усилия разработчиков систем параллельного программирования необходимо направить не на разработку новой модели параллельного программирования и ее представления в виде нового языка параллельного программирования, а на инструментальные средства, помогающие разрабатывать, оптимизировать и отлаживать параллельные программы в рамках старой, хорошо понятной прикладным программистам модели передачи сообщений. Что касается повышения уровня параллельного программирования, то от универсальных моделей следует перейти к специализированным (многие такие модели, например для задач линейной алгебры уже разработаны [13]). А для разработки специализированных моделей, как известно, наиболее удобны объектно-ориентированные языки программирования. Сейчас наиболее популярны два языка объектно-ориентированного программирования – C++ и Java. Каждый из них имеет свои достоинства и недостатки. Так, C++ более приближен к компьютеру, на нем можно писать столь же эффективные программы, как и на C, расширением которого он является. Поэтому большинство объектно-ориентированных языков параллельного программирования базируется на C++. Java – интерпретируемый язык: Javaпрограммы выполняются на интерпретаторе Java – JavaVM, что, естественно, замедляет их выполнение. Но зато Java-программы являются полностью переносимыми, так как окружение Java одинаково на всех компьютерах. И если первое обстоятельство заставляет воздержаться от применения Java в параллельном программировании, то независимость системы программирования Java от особенностей аппаратуры компьютера, несомненно, полезна для параллельных программ.
В модели SPMD на всех узлах (процессорах) компьютерной сети выполняется одна и та же последовательная программа. Следовательно, для описания параллельных вычислений в рамках этой модели нет необходимости вводить какие-либо новые операторы языка, достаточно ввести средства описания распределения данных по узлам и операции обмена данными между узлами. В объектно-ориентированном языке обе эти проблемы можно решить с помощью подходящих библиотек классов. Для обеспечения эффективности необходимо, чтобы эти библиотеки классов опирались непосредственно на новую систему поддержки выполнения скомпилированной программы (run-time system), являющуюся расширением соответствующей системы исходного объектно-ориентированного языка. От эффективности расширенной системы поддержки выполнения существенно зависит эффективность параллельных программ, разрабатываемых в ее рамках. При этом если расширяемым объектноориентированным языком является язык Java, необходимо, чтобы расширение системы поддержки выполнения не затрагивало Java VM, т.е. было внешним по отношению к Java VM. Если это условие не выполняется (как, например, в работе [14]), то вместо стандартной Java VM, получается расширенная Java VM, байт-код которой содержит дополнительные инструкции, отражающие специфику параллельного выполнения. Конечно, такое решение позволяет повысить эффективность выполнения (интерпретации) параллельной Java-программы, но оно противоречит требованиям системы программирования Java. Параллельные программы, написанные на таком расширении, могут выполняться лишь на тех параллельных вычислительных комплексах, на которых установлена расширенная Java VM. При реализации расширения системы поддержки выполнения вне рамок стандартной Java VM параллельная программа может выполняться на всех процессорах, на которых установлена система программирования Java. При этом достаточно высокая эффективность параллельной программы может быть достигнута за счет реализации подпрограмм, расширяющих стандартную Java VM, на языке ассемблера соответствующего процессора (Java VM позволяет вызывать и выполнять подпрограммы на языке процессора, на котором она установлена). В данной работе рассматриваются расширения системы программирования Java с помощью системных библиотек классов. Такие расширения не требуют для своей работы ни расширения Java VM, ни специальных компиляторов или препроцессоров. Только такой подход позволяет разрабатывать параллельные программы, переносимые как на новую аппаратнопрограммную платформу, так и на новую версию системы программирования Java. Пример параллельной программы с рис. 1 на языке Java с
31 использованием библиотеки классов DPJ приведен на рис. 4. В основе предлагаемых библиотек классов лежат объектные модели параллельных вычислений. Как уже отмечалось, в работе рассматривается две такие модели: модель DPJ (п. 3.1) и модель DVM (п. 3.2).
3. Объектные модели параллельных вычислений 3.1 Модель DPJ Модель DPJ [15] относится к классу моделей SPMD, в котором параллельная программа рассматривается как набор функционально одинаковых компонент (последовательных программ). В модели DPJ каждая компонента представляет собой последовательную Javaпрограмму, выполняемую на отдельной JavaVM, причем все компоненты и их JavaVM работают одновременно на процессорах параллельного компьютера. Для организации взаимодействия и обмена данными между компонентами используется пакет передачи сообщений MPI (Message Passing Interface) [7]. Пакет MPI позволяет скрыть физическую структуру процессоров комплекса, используемых сетевых средств, а также особенности операционных систем, представляя набор примитивов для управления передачей сообщений. Одним из важных примитивов пакета MPI является процесс. Процесс – это единица исполнения программы, причем обмен сообщениями в MPI производится только между процессами. MPI позволяет запускать потенциально бесконечное множество процессов на параллельном вычислительном комплексе. В работе каждой компоненте параллельной Javaпрограммы ставится в соответствие один процесс MPI. Таким образом, параллельная Java-программа отображается на множество процессов MPI. Это множество процессов MPI удобно называть сетью, а каждый процесс – узлом этой сети. Сеть концептуально создается с помощью специальных классов запуска ее множества узлов, определяющих ее мощность и параметры запуска параллельной программы. В рамках принятой модели компоненту параллельной программы можно ассоциировать с узлом, на котором она выполняется. Поскольку на каждом узле выполняется Java-программа, в ней можно применять средства параллелизма, определенные в языке Java (классы Thread, ThreadGroup), использующие модель параллелизма на общей памяти. В работе рассматривается только модель параллелизма на распределенной памяти, т.е. предполагается, что каждая компонента параллельной программы работает в своем отдельном адресном пространстве, а трэды действуют в рамках одного узла, причем реальный параллелизм может достигаться, если сам узел имеет сложную структуру (т.е. процесс MPI выполняется на
многопроцессорной архитектуре с поддержкой распределения трэдов по различным процессорам). Определение подсетей. Выделение подсети некоторой сети или подсети осуществляется с помощью создания экземпляра объекта специального класса Subnet. Каждая подсеть имеет родительскую сеть или подсеть и может иметь произвольное количество сыновних подсетей. В текущей реализации библиотеки создание сети или подсети приводит к созданию соответствующих группы и коммуникатора MPI. Создание коммуникатора MPI требует одного акта коллективной коммуникации по соответствующей надсети. Распределенные контейнеры. В языке Java, как и в других объектно-ориентированных языках, доступ к наборам однотипных объектов удобно представлять с помощью контейнерных объектов (контейнеров). Примерами контейнеров являются массивы, векторы, списки, множества, множества ключей и др. Каждый объект, доступ к которому организуется через контейнер, называется элементом этого контейнера. Итератор контейнера – это объект, который обеспечивает доступ к элементам контейнера. В последовательной программе в произвольный момент времени итератор обеспечивает доступ не более чем к одному элементу. Итератор удобно использовать для организации циклов обработки элементов контейнера. Для реализации распараллеливания по данным введем распределенный контейнер, который размещает свои элементы по одному на каждом узле некоторой подсети N. Подсеть N указывается при определении (порождении) соответствующего распределенного контейнера. Как и в обычном контейнере, каждый элемент распределенного контейнера может иметь ссылки на другие элементы этого контейнера: в этом случае ссылка указывает узел, на котором располагается элемент, адресуемый этой ссылкой. Над распределенным контейнером могут быть определены операции типа свертки, выполняемые параллельно с максимальной эффективностью над всеми его элементами. Примерами таких операций являются: подсчет количества элементов в контейнере, получение индекса элемента, сложение всех элементов контейнера (например, распределенного массива), нахождение максимума и минимума, и т.п. Строгая типизация элементов контейнера может осуществляться с помощью типизированных итераторов и адаптеров. В настоящее время в библиотеку DPJ включены следующие распределенные контейнеры: 1. Распределенный массив – это распределенный контейнер с фиксированным количеством элементов (узлов), не имеющих связей между собой. К распределенным массивам применяются итераторы с произвольным доступом. Количество узлов в массиве задается при его определении и остается постоянным в процессе выполнения программы.
32 2. Распределенный вектор – отличается от распределенного массива лишь тем, что количество узлов в контейнере может изменяться в процессе выполнения программы. 3. Распределенный список – это распределенный контейнер, у которого заданы: головной узел, промежуточные узлы и хвостовой узел. Если список состоит из одного узла, то этот узел является головным и хвостовым одновременно. К распределенным спискам применяются итераторы с последовательным доступом. Количество элементов в списке может изменяться в процессе выполнения программы. 4. Распределенное дерево – это распределенный контейнер, у которого имеются корневой узел, нетерминальные узлы и листовые узлы. Если дерево состоит из одного узла, то этот узел является корневым и листовым одновременно, причем у него нет ни сыновнего, ни родительского узлов. В остальных случаях корневой узел не имеет родительского узла, но имеет несколько сыновних. Листовой узел не имеет сыновнего узла, но имеет один родительский. Все нетерминальные узлы имеют один родительский и несколько сыновних узлов, причем эти узлы являются различными. К распределенным деревьям применяются итераторы с последовательным доступом. Количество элементов в дереве может изменяться в процессе выполнения программы. Итераторы распределенных контейнеров. Итератор распределенного контейнера – это объект, распределенный по той же подсети, что и контейнер, и обеспечивающий доступ одновременно ко всем элементам одного из подмножеств узлов этого контейнера. Это подмножество узлов контейнера называется значением итератора. Множество всех значений итератора образует покрытие множества узлов контейнера (с пересечениями или без пересечений). У итератора определены две операции: присваивание и переприсваивание его значения. С помощью этих операций итератор может попеременно принимать все свои значения, в совокупности составляющие покрытие множества всех узлов контейнера. Существует специальное значение итератора, множество узлов которого является пустым, которое используется для завершения итерационного процесса. Итераторами распределенных контейнеров могут служить объекты классов, в которых реализован хотя бы один из интерфейсов, определенных в библиотеке. • Множественный итератор (DMultiIterator) – это итераторы, значения которых есть подмножества множества узлов контейнера. Мощность этих подмножеств может меняться от значения к значению. • Унарный итератор (DUnaryIterator ) – это итератор, представляющий работу с множеством, состоящим из одного узла контейнера.
•
Полный итератор (DAllIterator) – это итератор, единственным значением которого является множество всех узлов контейнера. Параллельные алгоритмы. Параллельный алгоритм – это распределенный контейнер или итератор, специально оптимизированный для параллельного выполнения алгоритмов. В библиотеке DPJ содержатся стандартные классы, реализующие часто используемые параллельные алгоритмы для работы с распределенными контейнерами. Все библиотечные параллельные алгоритмы реализуют интерфейс ParallelAlgorithm, содержащий следующие методы: • Запустить (остановить, или приостановить) метод run(), runTop(), или runBottom(). • Сами методы run(), runTop()и runBottom(). В настоящее время реализованы следующие параллельные алгоритмы: • Applying – применяет указываемый функциональный объект к элементам контейнера. • Copying – копирует распределенный контейнер (возможно, с обращением порядка элементов). • Comparing – параллельное попарное сравнение элементов распределенных контейнеров. • Finding – параллельный поиск элементов в распределенном контейнере по шаблону. • Filtering – параллельный отбор элементов в распределенном контейнере по шаблону. • Replacing – параллельная замена элементов распределенного контейнера. import dpj.*; public class Test { final private static int BUF_SIZE = 512; public static void main( String[] args ) { Subnet n = new Subnet( Subnet.netWorld, 2 ); DArrayFixedIntArrayClass DArrayFixedIntArrayClass(
a n,
= new BUF_SIZE
); DMyIterator init = new DMyIterator( a, 0 ); init.start(); A.putValue( 1, a.getValue( 0 ) ); } } class DMyIterator extends DunaryInputIterator { DMyIterator( int root ) { super( root ); } public void run() { int[] a = (int[])container().get(); // Инициализация массива container().put( a ); } }
Рис. 4. Параллельная программа с рис.1, записанная на языке Java с использованием библиотеки классов DPJ • Sorting – параллельная сортировка элементов распределенного контейнера.
33 • Transforming – параллельное преобразование распределенного контейнера. На рис. 4 представлена программа с рис.1, реализованная с помощью библиотеки DPJ. Это обычная Java-программа, она не содержит новых языковых конструкций и потому привычна для программиста, который ее разрабатывает. Использование распределенных параллельных вычислений осуществляется с помощью точно таких же языковых средств (библиотечных классов), как и ввод-вывод или использование параллельных вычислений над общими данными (трэды языка Java). 3.2 Модель DVM Модель DVM (Distributed Virtual Machine) [6], разработанная в ИПМ им. М.В. Келдыша РАН, тоже относится к классу моделей SPMD. В основе модели DVM лежат понятия абстрактной параллельной машины (АПМ) и виртуальной параллельной машины (ВПМ). АПМ представляет собой многомерный массив абстрактных параллельных подсистем, каждая из которых является многомерным массивом процессоров, либо подсистем следующего уровня и далее по рекурсии. АПМ может быть задана в программе статически, или построена динамически при выполнении программы. Динамическое построение АПМ необходимо при работе с динамическими массивами, а также для использования библиотек стандартных параллельных программ, хранящихся в виде объектных модулей и не требующих предварительной настройки. При разработке программы для АПМ пользователь исходит из следующей модели ее выполнения. В момент старта программы существует единственная ее ветвь (поток управления), которая выполняется на одном из процессоров АПМ, начиная с первого оператора программы. При входе в параллельную конструкцию, например, параллельный цикл или группу параллельных секций, ветвь разбивается на некоторое количество параллельных ветвей, каждая из которых выполняется на одном процессоре (или подсистеме) АПМ. При выходе из параллельной конструкции все ветви снова сливаются в единственную ветвь, которая выполнялась до входа в эту конструкцию. В этот момент все изменения разделяемых переменных, которые были произведены параллельными ветвями, становятся видны всем процессорам, выполняющим программу. Формальная зависимость параллельных ветвей по данным устраняется путем объявления некоторых переменных приватными. Тогда для каждой параллельной ветви заводится своя копия (неинициализированная) таких переменных, которая используется независимо от других. Все остальные данные, используемые параллельными ветвями, считаются разделяемыми. Режим доступа к разделяемым переменным в параллельных ветвях может быть специфицирован как только чтение; распределенный доступ (например, разные витки цикла используют различные элементы массива) и
произвольный доступ. В случае произвольного доступа, программист должен осуществлять явную синхронизацию параллельных ветвей. ВПМ – это машина, которая предоставляется задаче пользователя аппаратурой и базовым системным программным обеспечением. Эта машина по своей структуре и количеству процессоров должна быть близка к реальной параллельной ЭВМ. Примером ВПМ может служить MPI-машина. ВПМ также может быть представлена в виде иерархии подсистем. При этом должен быть однозначно определен состав каждой подсистемы – номера входящих в нее процессорных узлов ВПМ. Каждая подсистема может содержать только те процессоры, которые входят в состав ее материнской подсистемы. Модель DVM не предполагает динамического изменения состава ВПМ, поскольку в распределенных системах подключение нового процессора требует переноса на него контекста программы и связано с большими накладными расходами. Отображение АПМ на ВПМ машину заключается в задании соответствия между подсистемами АПМ и ВПМ, в результате которого каждая подсистема АПМ будет отображена на подсистему или процессор ВПМ. При этом используются два метода задания такого соответствия: • Отображение указанной подсистемы АПМ на указанную подсистему ВПМ. Ветвь, отображенная на такую подсистему АПМ, будет выполняться на всех процессорах соответствующей подсистемы ВПМ. • Регулярное (блочное или циклическое) распределение всех дочерних подсистем АПМ между указанной подсистемы процессорами указанной подсистемы ВПМ. При этом подсистема АПМ (и ее дочерние подсистемы) специфицируется путем задания одного из своих представлений. При распараллеливании программы на системах с распределенной памятью необходимо задать расположение данных в локальной памяти процессоров АПМ. Это осуществляется посредством выравнивания массивов между собой и отображением их на подсистему АПМ в соответствии с указанным ее представлением в виде многомерного массива подсистем следующего уровня иерархии. При этом допускается сжимающее отображение (все элементы какого-то измерения отображаются на одну подсистему) и размножающее отображение (один элемент массива дублируется на многих подсистемах). Дублирование данных производится в тех случаях, когда их вычисления выгоднее выполнять многократно на разных процессорах вместо того, чтобы заниматься их пересылкой между процессорами. Кроме того, дублируются данные, о расположении которых пользователь указаний не задал. Эти данные дублируются по всем процессорам подсети, на которой выполняется ветвь, содержащая описания этих данных.
34 Описание объектной модели библиотеки Java-DVM. Библиотека классов Java-DVM является реализацией модели DVM в среде Java. Распределение данных в Java-DVM осуществляется путем “разрезания” некоторых массивов на части и размещения этих частей на разных JavaVM. Такое “разрезание” осуществляется путем разделения какого-либо измерения массива на отрезки. При этом многопроцессорная система из P процессоров, на которой будет выполняться параллельная программа, рассматривается как многомерная решетка (матрица) процессоров, например, как двумерная решетка размера P1 на P2 (P1*P2=P). В этом случае одно из измерений массива может быть разделено на P1 отрезков, а какое-либо другое – на P2 отрезков. В результате массив будет разрезан на P1*P2 секций, каждая из которых будет отображена на соответствующий процессор двумерной решетки. Такие массивы называются распределенными массивами. Остальные массивы (а также скаляры) называются размноженными и размещаются на каждом процессоре целиком. Доступ к удаленным данным осуществляется путем их буферизации в памяти процессоров и обменом буферов сразу для нескольких витков цикла одновременно. Выделение буферов для хранения копий удаленных данных, посылка и прием сообщений с копиями удаленных данных, а также замена обращений к удаленным данным на обращения к их копиям в буферах – все это осуществляется методами классов библиотеки Java-DVM. На рис. 5 представлена объектная модель библиотеки Java-DVM. Описание виртуальной параллельной машины осуществляется методами класса Subnet. Для описания абстрактной параллельной машины предназначены следующие классы: класс Darray, реализующий параллельные массивы; классы Dforall и DForeach, реализующие параллельные циклы, класс PSection реализующий группу параллельных секций. Отображение АПМ на ВПМ осуществляется методами класса Dtemplate, а буферизация и локализация удаленных данных – методами класса Shadow. Класс Array позволяет моделировать многомерные массивы с помощью одномерных. Распределение данных. В библиотеке JavaDVM многомерные массивы моделируются на одномерном массиве. Каждый многомерный массив является объектом класса Array. В рамках этого класса реализованы операции доступа к элементам массива и его подмассивов, а также некоторые стандартные операции над массивом: перестановка строк, столбцов, транспонирование и пр. Способ распределения подмассивов данного массива между процессорами задается в объектах класса Dtemplate. Реализованы следующие три способа распределения данных: • Блочный: элементы i-го измерения массива отображаются на процессоры непрерывными блоками.
•
Циклический: элементы i-го измерения массива отображаются на процессоры циклически. • Отображаемый: элементы массива не распределяются между процессорами, а целиком отображаются на каждый процессор. Распределение вычислений. Параллельная программа, использующая библиотеку классов Java-DVM, выполняется в модели SPMD: на все JavaVM загружается одна и та же программа, но каждая JavaVM в соответствии с правилом собственных вычислений выполняет только те операторы присваивания, которые изменяют значения переменных, размещенных на ней. Таким образом, вычисления распределяются в соответствии с размещением данных (параллелизм по данным). В случае размноженной переменной оператор присваивания выполняется на всех процессорах, а в случае распределенного массива – только на процессоре (или процессорах), где размещен соответствующий элемент массива. Ответственность за согласованное распределение вычислений и данных полностью возлагается на пользователя.
.Рис 5. Объектная модель Java-DVM Отображение витков параллельного цикла осуществляется блочно – на каждый процессор отображается сразу несколько соседних витков цикла. Кроме того, если имеется гнездо тесно вложенных циклов, оно может быть специфицировано как единый многомерный параллельный цикл. Для реализации параллельных циклов используются абстрактные классы DForall и Dforeach, имеющие абстрактный метод Body. Создав класс, родителем которого является один из этих классов, можно описать тело параллельного цикла. Витки цикла DForall могут выполняться в произвольном порядке. Витки цикла DForeach выполняются строго последовательно, в рамках одного процессора. Часто в программе встречаются циклы, в которых выполняются редукционные операции – в некоторой переменной суммируются элементы массива или находится их максимальное
35 или минимальное значение. Эти циклы так же могут выполняться параллельно, методом reduce класса DArray. Организация доступа к удаленным данным. После спецификации распределения данных и витков циклов программа готова к параллельному выполнению при условии, что все данные, необходимые процессору, размещены на этом процессоре. Для большинства программ это условие не выполняется. Предусмотрены средства, позволяющие использовать удаленные данные. Импортируемыми данными процессора будем называть используемые им данные, расположенные на других процессорах. Основной способ оптимизации доступа к удаленным данным уменьшение количества импортируемых данных. Это достигается совместным распределением нескольких массивов (выравнивание массивов). При выравнивании массивов возможны следующие виды соответствия: • совмещение двух массивов одинаковой формы (одинаковой размерности и с одинаковыми размерами в каждом измерении); • совмещение двух массивов одинаковой формы с реверсом (первому элементу одного массива соответствует последний элемент другого); • совмещение двух массивов с поворотом (jое измерение одного массива совмещается с k-ым измерением другого); • вложение меньшего массива в больший со сдвигом, не приводящим к выходу за пределы большего массива; • вложение меньшего массива в больший с раздвижкой (например, каждому элементу первого массива с индексом i соответствует элемент второго массива с индексом 2*i); • размножение массива меньшей размерности; • отображение массива меньшей размерности на секцию другого массива, получающуюся путем фиксации индексов в некоторых его измерениях; • сжатие измерения массива большей размерности; • выравнивание массивов (осуществляется с помощью методов класса DArray). Если перед выполнением цикла скопировать грани импортируемых данных в соответствующие теневые грани, то цикл можно выполнять без доступа к удаленным данным. Теневые грани задаются методом setShadow класса Shadow Максимальная ширина теневых граней может задаваться пользователем. По умолчанию максимальная ширина теневых граней по каждому измерению равна 1. Методом renewShadow можно уточнить размеры теневых граней (задать меньше, чем было задано при первоначальной установке). Перезапись в теневые грани (обновление) осуществляется перед параллельным циклом.
Если импортируемые переменные не являются “соседними” и для доступа к ним нельзя использовать теневые грани, то их буферизация осуществляется через отдельный буферный массив. Методом setBuffer класса DArray задается, какая часть массива должна быть буферизована на каждом процессоре. Размер этой части определяет размер буфера. Совмещение счета и обменов данными между процессорами. Обновление значений теневых граней выполняется каждым процессором в два этапа: сначала запускаются операции обмена данными – операции посылки экспортируемых данных локальной секции массива и операции приема значений теневых граней; затем ожидается завершение выданных операций. На фоне этого ожидания можно выполнять вычисления по внутренним элементам секции массива, если этапы операции обновления теневых граней задавать с помощью отдельных директив (запуск операции и ожидание ее окончания). Если перед циклом необходимо обновление теневых граней нескольких массивов, то эти операции можно объединить в одну групповую операцию обновления, что также может уменьшить накладные расходы. Организация группового асинхронного обновления теневых граней осуществляется методом groupShadow класса Shadow. Обновление теневых граней (посылка и прием экспортируемых данных) реализуется методом startShadow. Ожидание завершения обновления теневых граней осуществляет метод waitShadow. Мы не приводим примера параллельной программы с использованием библиотеки JavaDVM, так как соответствующая программа представляет собой программу с рис. 2, записанную в объектно-ориентированном виде (это связано с тем, что модель DVM имеет много общего с моделью, лежащей в основе системы HPF 2).
4. Примеры параллельных программ. Анализ производительности. Рассмотрим несколько примеров параллельных программ, разработанных для тестирования библиотек DPJ и JavaDVM. Тексты соответствующих программ, а также тексты исходных модулей библиотек DPJ и JavaDVM доступны через Internet, адрес сайта www.ispras.ru/~dpj. Параллельная версия программы QuickSort в модели DPJ. В качестве примера использования распределенных контейнеров и их итераторов, определенных в модели DPJ, рассмотрим алгоритм параллельной сортировки массива целых чисел, основанный на последовательном алгоритме QuickSort. В алгоритме используется распределенное сбалансированное бинарное дерево с полностью заполненными уровнями.
36 матрицы представляют собой соответствующие индексы строк и столбцов блоков матрицы. На рис. 6b представлен другой способ распределения той же матрицы: на каждый из процессоров помещается 64 блока распределённой матрицы. Программа решения системы алгебраических уравнений с помощью алгоритма Холесского.
Рис. 6. Примеры распределения данных
блочно-циклического
Коммуникационные характеристики алгоритма и баланс загрузки процессов существенно зависят от распределения элементов матрицы между узлами вычислительной сети. Для алгоритма Холесского хорошие результаты по быстродействию получаются при использовании блочно-циклического распределения. Количество процессоров 1 2 4 6 8
Время (миллисекунды) 40224 30 488 22 744 18 883 15 995
Ускорение 1.00 1.32 1.77 2.13 2.51
Рис. 7. Результаты измерений быстродействия параллельной программы, реализующей разложение Холесского 45000 40000 Время, миллисекунды
В начальный момент исходный массив размещается на корневом узле дерева. Определяется множественный итератор, обходящий дерево по уровням, имеющий корневой узел в качестве начального значения. На множестве узлов, принадлежащих значению итератора, запускается параллельный алгоритм, который разбивает сортируемый массив на две части так, как это делается в последовательном алгоритме QuickSort. Затем левая часть массива отправляется левому поддереву текущего узла, а правая – правому. На следующей итерации новое значение итератора есть множество всех узлов, составляющих следующий уровень дерева. На этой итерации каждая из сыновних вершин нового уровня получает свою часть массива от родительского узла и производит соответствующие действия. Работа алгоритма продолжается до достижения итератором значения, содержащего множество всех листовых узлов дерева. На листовых узлах оставшийся массив сортируется последовательным алгоритмом QuickSort. Дальнейшее приращение значения итератора приводит к получению им специального значения at-end, и алгоритм завешает свою работу. Результатом работы алгоритма является отсортированный массив, распределенный по листовым узлам дерева. Алгоритм был запрограммирован и выполнен на сети из 8 процессоров UltraSPARC 167 МГц и 128 Мбайт оперативной памяти каждый. Блочно-циклическое распределение. Блочноциклическое распределение двумерного массива является одним из стандартных способов распределения массивов в системе программирования HPF. Оно характеризуется набором из четырёх чисел P, Q, m и n, где P×Q – решётка процессов, а m×n – размер блока исходной матрицы. Блочно-циклическое распределение фиксирует шаг, с которым назначаются строки и столбцы матрицы каждому процессорному узлу вычислительной сети. Пусть дано M массивов (блоков исходной матрицы), проиндексированных целыми значениями 0, 1, …, M-1. В блочно-циклическом распределении глобальный индекс m представляет собой тройку чисел (p, b, i), где p - логический номер узла, b - номер блока находящегося на узле p и i индекс внутри блока b. Распределение блочной матрицы можно представить в виде совокупности двух отображений: первое это распределение строк матрицы между P процессорами, второе – распределение столбцов между Q процессорами (если решётка процессорных узлов имеет размеры P×Q). На рис. 6a представлен пример блочноциклического распределения данных для двухмерного массива (матрицы), содержащего 11 строк и столбцов. Пронумерованные прямоугольники представляют собой блоки, на которые разделена матрица, а номер указывает на какой процессор помещён соответствующий блок – все блоки с одинаковыми номерами находятся на одном процессоре. Номера сверху и слева от
35000 30000 25000 20000 15000 10000 5000 0 1
2
4 Количество процессоров
6
8
Рис. 8. Зависимость времени выполнения алгоритма Холесского от числа процессоров в сети
37 На рис. 7, 8 и 9 приводятся результаты измерений производительности параллельной версии алгоритма Холесского, который был реализован с помощью библиотеки DPJ. В программе использовалась матрица размера 240240 элементов, вычислительный комплекс состоял из кластера рабочих станций UltraSparc-1 с процессором UltraSPARC 167 МГц и 128 Мбайт оперативной памяти каждая. Все станции соединены 100 Мбитной сетью Ethernet. Оборудование любезно предоставлено администрацией IRISA/INRIA. Как показывают результаты, представленные на рис. 7, 8 и 9, использование библиотеки DPJ обеспечивает ускорение выполнения параллельных Javaпрограмм по сравнению с их последовательными версиями. Из графика, представленного на рис. 9, видно, что программа показывает удовлетворительные результаты по масштабируемости: при увеличении количества процессоров в сети ускорение программы возрастает пропорционально числу процессоров в сети.
Рис. 9. Зависимость ускорения выполнения алгоритма Холесского для матрицы размером 240×240 Как показывают результаты, представленные на рис. 7, 8 и 9, использование библиотеки DPJ обеспечивает ускорение выполнения параллельных Java-программ по сравнению с их последовательными версиями. Из графика, представленного на рис. 9, видно, что программа показывает удовлетворительные результаты по масштабируемости: при увеличении количества процессоров в сети ускорение программы возрастает пропорционально числу процессоров в сети. Как показывают результаты, представленные на рис. 7, 8 и 9, использование библиотеки DPJ обеспечивает ускорение выполнения параллельных Java-программ по сравнению с их последовательными версиями. Из графика, представленного на рис. 9, видно, что программа показывает удовлетворительные результаты по масштабируемости: при увеличении количества процессоров в сети ускорение программы возрастает пропорционально числу процессоров в сети.
5. Заключение Параллельное программирование в модели SPMD не требует специальных языковых средств для описания параллельной программы, так как
такие средства дают лишь одну дополнительную возможность – более простые системные способы описания распределения данных между процессорами вычислительной сети и, как следствие этого, автоматическую генерацию операторов обмена данными между процессорами сети. Как оказалось, эта возможность не привлекает прикладных программистов, так как она лишает их средств оптимизации приложений по обменам данными, т.е. не позволяет выразить наиболее важные аспекты многих прикладных параллельных алгоритмов. Прикладные программы, в которых применение системных способов распределения данных оправдано, составляют лишь узкий класс. В других приложениях удобны другие, менее общие, способы распределения данных. Следовательно, язык для описания параллельных вычислений должен допускать много различных способов распределения данных между процессорами. Наиболее просто это можно реализовать в объектно-ориентированном языке. Конечно, требования высокого быстродействия вынуждают брать в качестве базового объектноориентированного языка такой язык как C++, позволяющий писать программы с высоким быстродействием, но, к сожалению, C++ не является строго объектно-ориентированным языком, что затрудняет его использование в качестве базы для изучения особенностей объектно-ориентированного параллельного программирования. Поэтому в данной работе, которая имеет не прикладную, а исследовательскую направленность, в качестве базового языка был взят менее эффективный, но более строгий объектно-ориентированный язык Java. Библиотеки для языка Java, описанные в работе, легко переписываются на C++. Кроме того, близкие результаты для C++ содержатся в работе [12]. Относительно этой работы интересно отметить, что в начале язык Charm, лежащий в ее основе, представлял собой параллельное расширение языка C, но популярность приобрел не Charm, а его объектно-ориентированная версия Charm++, которая, по существу представляет набор системных библиотек на C++. Эксплуатация библиотек DPJ и JavaDVM показала их удобство для разработки прикладных параллельных программ. В настоящее время они используются для разработки прикладного пакета для расчета прочности оболочек из композитных материалов. Дальнейшие наши планы связаны с разработкой и реализацией инструментальных средств, поддерживающих отладку и мониторинг параллельных программ. Эти диалоговые средства позволят прикладному программисту улучшать характеристики своей параллельной программы. Библиография 1. J. Gosling, “The Java Language Environment”, white paper, Sun Microsystems, Mountain View, Calif., 1995; http://java.sun.com 2. Ted G. Lewis, Foundations of Parallel Programming: A Machine Independent Approach, IEEE Computer Society Press, Los Alamitos, CA, 1993.
38 3. Nan's Parallel Computing Page http://www.cs.rit.edu/~ncs/parallel.html 4. HPF: High Performance Fortran Language Specification, High Performance Fortran Forum, version 2.0, January 31 1997; http://www.crpc.rice.edu/HPFF/hpf2/index.html 5. MPC++ Version 2:Massively Parallel, Message Passing, Meta-level Processing C++ http://www.rwcp.or.jp/lab/mpslab/mpc++/mpc++.html
6. N.A. Konovalov, V.A. Krukov, S.N. Mihailov and A.A. Pogrebtsov, “Fortran-DVM language for portable parallel programs development”, Proceedings of Software for Multiprocessors and Supercomputers: Theory, Practice, Experience (SMS-TPE 94), Inst. for System Programming RAS, Moscow, Sept. 1994. 7. MPI: Message Passing Interface Standard, Message Passing Interface Forum, June 12 1995; http://www.mcs.anl.gov/mpi/index.html 8. D. Wood, P. Welch OCCAM 2: Kent Retargetable Occam Compiler. http://www.idiom.com/freecompilers/LANG/OCCAM2-1.html 9. G.A. Geist, J.A. Kohl, P.M. Papadopoulos. PVM and MPI. A Comparison of Features. Calculateurs Paralleles Vol. 8 No. 2 (1996), http://www.epm.ornl.gov/pvm/pvm_home.html 10. Nicolau, David Gelernter, T. Gross, and D. Padua, editors. Advances in Languages and Compilers for Parallel Computing. The MIT Press, 1991. 11. Nicholas Carriero and David Gelernter. Linda and Message Passing: What Have We Learned? Technical Report 984, Yale University Department of Computer Science, Sept. 1993. http://www.cs.yale.edu/Linda/techreports.html 12. Dmitry Arapov, Alexey Kalinov, Alexey Lastovetsky, Ilya Ledovskih, and Ted Lewis, "A Programming Environment for Heterogeneous Distributed Memory Machines", Proceedings of 6th Heterogeneous Computing Workshop (HCW'97), IEEE Computer Society, Geneva, Switzerland, April 1997, pp.32-45 13. Standard Library for Parallel Programming, http://charm.cs.uiuc.edu/ 14. ScaLAPACK Users' Guide, http://www.netlib.org/scalapack/slug/scalapack_slug.html 15. Susan F. Hummel, Ton Ngo, Harini Srinivasan, “SPMD Programming in Java”, tech. report, IBM T.J. Watson Research Center; http://www.npac.syr.edu/projects/javaforcse/cpande/IBM spmdjava_new.ps 16. V. Ivannikov, S. Gaissaryan, M. Domrachev, V. Etch, N. Shtaltovnaya. DPJ: Java class library for development of data-parallel programs. http://www.ispras.ru/~dpj
Формальные спецификации в технологиях обратной инженерии и верификации программ И.Б. Бурдонов, А.В. Демаков, А.С. Косачев, А.В. Максимов, А.К. Петренко
Аннотация KVEST (Kernel Verification and Specification Technology) – технология спецификации и верификации программного обеспечения, основанная на автоматизированной генерации тестов из формальных спецификаций. Эта технология была разработана в рамках контракта с Nortel Networks и базируется на опыте, полученном в результате академических исследований. К 1999 году методология и набор инструментов применялись в трех индустриальных проектах верификации телекоммуникационного ПО. Первый проект, The Kernel Verification project, дал название методологии и набору инструментов. Результаты этого проекта присутствуют в Formal Method Europe Application database [28]. Это одно из крупнейших приложений формальных методов, присутствующих в базе данных. Данная статья содержит краткое описание подхода, сравнение со сходными работами и перспективы развития*.
1. Введение 1.1 Обратная и прямая инженерия ПО Задачи программной инженерии (software engineering) условно можно разделить на две большие группы – реверсили обратная инженерия и форвардинженерия (reverseand forwardengineering). Разные исследователи и практические разработчики программного обеспечения (ПО) уделяют этим группам разную долю внимания, однако сейчас уже ни одна промышленная разработка не может игнорировать проблемы каждой из этих групп. Форвард-инженерия необходима для того, чтобы поддерживать поступательное развитие ПО, реверсинженерия необходима для поддержки преемственности функциональности и таких характеристик как надежность, управляемость, открытость к изменениям и *
Часть работ по развитию методологии была выполнена в рамках грантов РФФИ 96-0101277 и 99-01-00207.
др. В контексте индустриальной разработки и развития ПО важно объединение методов и технологий анализа и создания ПО. При недооценке важности такого объединения легко оказаться в ситуации, когда одни фазы жизненного цикла ПО получают гипертрофированно развитые средства поддержки, что, в частности, приводит к росту объемов ПО, а другие фазы, не имея адекватной поддержки, встречаются с непреодолимыми трудностями. Очевидным примером здесь служит развитие языков программирования, в частности, объектноориентированных (ОО) языков и соответствующих компиляторов и интегрированных средств поддержки. Это привело к появлению чрезвычайно громоздких программных комплексов, поддержка, изучение и модификация которых становятся невозможным без специальных методов и инструментов. В данной статье "реверс-инженерия" часто предшествует "форвард-инженерии". Это объясняется двумя обстоятельствами. Во-первых, авторам ближе этот аспект, поскольку именно с реверс-инженерии начинались работы по созданию технологий, о которых пойдет речь ниже. Во-вторых, и это, может быть, более важно, задачи реверс-инженерии во многих отношениях проще формализуются, и по этой причине на задачах реверс-инженерии имеются реальные предпосылки для апробации самых новых методов и инструментов поддержки разработки и развития ПО. Простота формализации здесь обуславливается тем, что исходный материал для реверс-инженерии – это полностью формализованный программный материал – исходные тексты программ. В случае форвард-инженерии в качестве "исходного материала" выступают существенно менее материальные субстанции: методы проектирования, навыки разработчиков, неформальные спецификации требований и пр. Таким образом, несмотря на то, что целью статьи является развитие концепции единого подхода к решению задач реверс- и
40 форвард-инженерии, далее мы будем сохранять тот же порядок рассмотрения аспектов программной инженерии – сначала "реверс", а затем "форвард". 1.2 Формальные методы в разработке ПО Дать точное определение "формальным методам", как они понимаются в программировании, достаточно затруднительно. Одна из причин этого состоит в том, что программы и методы их компиляции и интерпретации несомненно являются формальными, поэтому и все методы разработки программ легко объявить формальными. Вместе с тем, под термином "формальные методы" скрывается нечто, отличающее рутинное написание текстов на языке программирования от анализа этих текстов и анализа поведения программ, заданных этими текстами, причем анализа по духу близкого к математическим исследованиям, использующего математические нотации и способы рассуждений и доказательств, принятые в математике. В связи с этим многие авторы дают определение "формальных методов" просто как методов разработки программ, в которых используются математическая нотация (notation) и/или математические рассуждения (reasoning). Мы готовы остановиться на этом определении, поскольку не видим причин искать лучшего. Формальные методы в программировании, по-видимому, появились практически одновременно с самим программированием. Из результатов советской программистской школы наибольшую известность получили работы А.А.Маркова (алгоритмы Маркова) [24] и работы А.А.Ляпунова [25] и его учеников (например, схемы Янова [26]). В более поздние годы много внимания формальным методам в СССР уделялось в работах киевских, новосибирских, ленинградских и московских ученых. Наиболее известной и распространенной формальной нотацией является нотация Бэкуса-Наура, использующаяся для описания синтаксиса формальных языков. Затем можно назвать машину Тьюринга, конечные автоматы (Finite State Machine – FSM or Finite Automata – FA), сети Петри, языки описания взаимодействующих процессов К.А.Хоара (C.A.Hoar) и Р.Милнера (R.Milner) и др. По естественным причинам практически все работы по формальным методам были нацелены на форвард-приложения. В
качестве идеала рассматривалась следующая схема. На языке формальных спецификаций описываются функциональные требования к программной системе. Путем аналитического исследования устанавливается корректность спецификации – спецификация верифицируется. Затем при помощи некоторого инструмента на основе формальных спецификаций генерируется код программной реализации. Несколько более реалистичный сценарий дополнял описанную выше схему процессом постепенного уточнения спецификаций (refining). Каждый шаг уточнения проводится человеком, который направляет процесс уточнения. При этом соответствующие инструменты следят за тем, чтобы очередное уточнение спецификации не пришло в противоречие с исходными спецификациями. В обоих сценариях в качестве итогового результата должна появиться программная реализация, удовлетворяющая всем специфицированным требованиям и не содержащая ошибок. В 70-е годы появились языки формальных спецификаций, которые с одной стороны имели много общего с языками программирования, а с другой стороны предоставляли специальные средства, сближающие их с математической нотацией и облегчающие рассуждения о свойствах таких формальных текстов. В качестве наиболее известных упомянем CSP [13], CSS [14], VDM [15], SDL[16], LOTOS [17]. Несмотря на это, большая часть исследований по формальным методам попрежнему сохраняла так называемый "академический" характер. По-видимому, главным исключением служат работы по конечным автоматам (КА), которые нашли самое широкое применение в проектировании и тестировании средств автоматики, связи и вычислительной техники. Опыт использования КА в разработке аппаратуры применялся и в разработке ПО, хотя в существенно меньших масштабах по сравнению с разработкой аппаратуры. Весьма скромные результаты, продемонстрированные попытками применить формальные методы в реальных проектах, породили распространение скептического взгляда на возможность извлечь пользу из этих методов, соизмеримую с затратами, которые необходимо вложить в дополнительные
41 работы, связанные с разработкой и анализом формальных спецификаций. Вместе с тем, на отдельных направлениях формальные методы и, в частности, языки формальных спецификаций достигли значимых успехов. Эти успехи, с одной стороны, были обусловлены удачным сочетанием потребностей предметной области и возможностей формальных методов (в первую очередь это проблемы описания телекоммуникационных протоколов; SDL, LOTOS – примеры языков спецификаций, использующихся в этих областях), и с другой стороны, приближением языков спецификации к формам, привычным в традиционном программировании (в первую очередь это Венский метод – Vienna Development Method – VDM и его развитие – языки Z и RAISE). Еще одним фактором, создавшим предпосылку для продвижения формальных методов в реальное программирование (software production), стал интерес к вопросам реверс-инженерии вообще и к задачам автоматизации тестирования на основе использования формальных спецификаций (тем самым, спустившись с небес на землю, специалисты по формальным методам отбросили мечту об порождении программ без ошибок, а решили использовать свои методы для поиска ошибок, которые неизбежно встречаются в ПО). Главное преимущество, которое дает использование формальных методов в процессе реверс-инженерии, – это возможность строгого описания интерфейсов и поведения программной системы. Эта возможность, во-первых, позволяет фиксировать знания о функциональности отдельных компонентов и подсистем, знания о правилах взаимодействия, об ограничениях на входные данные, временные характеристики и др. Тем самым, появляется предпосылка для решения самой главной проблемы современной реверсинженерии. Она состоит в том, что на сегодняшний момент результатом работы по изучению программ (это и есть реверсинженерия в узком смысле этого слова) является знание отдельного индивида. Это знание не отчуждается от индивида и легко теряется как самим индивидом (и группой, в которой он работает), так и заказчиком реверс-инженерии, как только данный исполнитель переключился на другую работу. Известно, что фирмы производители ПО затрачивают огромные
средства на создание документации по ПО. Однако лишь немногие фирмы находят достаточно сил и времени, чтобы поддерживать документацию в актуальном состоянии. Эта ситуация каждый раз порождает необходимость в реверсинженерии. Реальным выходом из этого бесконечного цикла является фиксация так называемых "программных контрактов" (software contract), которые можно рассматривать как материальное представление знаний о функциональности данного ПО. Программный контракт описывает синтаксис и семантику интерфейсов систем. Как правило, этот термин используется по отношению к так называемым "интерфейсам прикладных программ" (Application Program Interfaces – API). API – это интерфейс, который предоставляется сущностями, составляющими программу, например, процедурами, функциями, методами ОО классов и т.п. Помимо собственно фиксации программного контракта, формальная спецификация позволяет систематизировать функциональное тестирование (часто называемое тестированием по методу "черного ящика"). Поскольку формальные спецификации строго описывают требования как на входные данные, так и на ожидаемые результаты, функциональных спецификаций достаточно для того, чтобы провести тестирование внешнего поведения системы. Заметим, что без строгих спецификаций такой систематизированный подход невозможен, поскольку нет данных ни об области допустимых воздействий на целевую систему, ни о критериях оценки полученных результатов – какие из результатов следует трактовать как правильные, какие как ложные. Это является одной из причин того, что большая часть исследований по тестированию посвящена тестированию на основе исходных текстов. Исходные тексты являются строгим описанием структуры реализации, поэтому они представляются подходящим материалом для извлечения тестов (тестовых воздействий) и для оценки полноты тестового покрытия. Однако, в отличие от функциональных спецификаций, на основании изучения исходных текстов нельзя вынести заключения о критериях проверки соответствия реализации ее функциональным требованиям, в частности, о полноте реализации. Еще одно обстоятельство является чрезвычайно важным. Если спецификации
42 формальны, то они могут рассматриваться как "машинно-читаемые". Тем самым появляется предпосылка полностью автоматизировать как генерацию тестов, так и анализ результатов тестирования. Серьезным направлением в использовании формальных методов в последние десять лет стала “проверка моделей” (model checking). Этот подход демонстрирует компромисс между идеальной мечтой о верификации формальной системы и реальной практикой разработки ПО. Суть похода состоит в построении модели реальной системы и по возможности полной проверке корректности данной модели. Проверка, если возможно, проводится аналитическими методами. Если это невозможно, производится тестирование модели. При этом сложность модели, как правило, выбирается таким образом, чтобы была возможность провести “исчерпывающее” тестирование (exhaustive testing). Слабое место данного подхода – это проблемы построения модели и доказательство того, что модель достаточно содержательна, чтобы на основании модели можно было судить о свойствах реальной системы. Резюмируя данный краткий обзор позитивных сдвигов в использовании формальных методов в индустриальной разработке ПО, отметим, что сейчас наметилось достаточно четкое разделение методологий и поддерживающих их инструментов, ориентированных на академические исследования и на использование в промышленности ПО. Последние отличаются от первых не только более развитыми средствами поддержки программных проектов, но и средствами, позволяющими перекинуть мостик между спецификациями и собственно целевой системой. К таким средствам в первую очередь относятся компиляторы исполнимых подмножеств языков спецификаций в языки программирования, средства согласования спецификационных и реализационных сущностей, средства, упрощающие конфигурирование целевых и тестовых систем, в которых часть компонентов создается вручную, а часть является результатом генерации из формальных спецификаций. Разнообразие таких возможностей позволяет заключить, что некоторые формальные методологии и наборы их инструментов уже вышли на уровень программных продуктов, и в ближайшее время следует ожидать значительного расширения как их
функциональности, так и масштабов их использования.
2. История и основные идеи KVEST 2.1 История разработки и использования KVEST В 1994 году Nortel Networks (предыдущие названия: Bell-Northern Research, Northern Telecom и Nortel) предложил ИСП РАН разработать методологию и комплект инструментов автоматизации тестирования интерфейсов прикладных программ (Application Program Interface – API). Первым практическим применением методологии стало ядро операционной системы реального времени. Был строго описан программный контракт ядра ОС и созданы тестовые наборы для проверки выполнения реализацией программного контракта. В случае успеха проекта Nortel получал возможность автоматизированной проверки соответствия программному контракту следующих версий ядра. Кроме того, появлялась возможность улучшить структуру программного продукта в целом, поскольку во время определения программного контракта ИСП предложил установить минимальное и ортогональное множество интерфейсов ядра ОС. ИСП организовал совместную группу исследователей и разработчиков. Члены группы имели богатый опыт в разработке операционных систем, систем реального времени, компиляторов и в использовании формальных спецификаций для систематического подхода к разработке и тестированию ПО [2, 9, 10]. За первое полугодие ИСП предложил первую версию интерфейсов ядра (Kernel Interface Layer – KIL) и произвел сравнительный анализ доступных методологий специфицирования. KIL был принят с незначительными модификациями. Наиболее подходящим языком спецификации был признан RSL (RAISE Specification Language) [11, 12]. За следующие полгода был разработан предварительный вариант методологии спецификации и генерации тестов, созданы прототипы спецификаций, разработан и реализован генератор тестовых оракулов. Прототип продемонстрировал возможность использования формальных спецификаций в промышленной разработке ПО. В качестве основного типа спецификаций были выбраны имплицитные спецификации. Также были установлены
43 основные принципы анализа тестового покрытия. KVEST методология использует модификацию СДНФ∗ критерия для разбиения пространства входных параметров, оценки тестового покрытия и выбора тестовой стратегии. За следующий год были созданы окончательные версии спецификаций и инструментов для генерации и выполнения тестов. С середины 1996 до начала 1997 года почти все тестовые наборы были получены и ядро ОС успешно протестировано. Результаты тестирования оказались неожиданными для заказчика. Никто не думал, что в критической части ПО, используемого в этой области более десяти лет, будет обнаружено несколько десятков ошибок! 2.2 Основные идеи KVEST Будем различать методологию и технологию, совокупность технических решений и инструментов, поддерживающих KVEST методологию. (На русском языке слово "методология" звучит слишком претенциозно, тем не менее мы его используем, поскольку это короче, чем "совокупность методов" и полностью адекватно трактовке слова "methodology" в англоязычной литературе). Методология KVEST нацелена на фиксацию программных контрактов и различные способы использования спецификаций программных контрактов. В качестве основного метода спецификации используется так называемый "моделе-ориентированный" или "ориентированный на состояние" (model based or state based) подход. Этот подход является альтернативным к так называемому "алгебраическому" подходу, синонимами которого являются "аксиоматический" и "действиеориентированный" (action based) подходы [21, 22]. В моделе-ориентированном подходе спецификация представляет собой привычную программистам совокупность функций и описаний данных, с которыми данные функции оперируют. Как правило, каждой операции (процедуре) целевой системы соответствует некоторая спецификационная функция. Со структурами данных картина существенно сложнее. Различаются "видимые" реализационные данные и скрытые. Видимыми всегда являются входные и выходные параметры операций (процедур, методов). Такие данные, как глобальные ∗
СДНФ – совершенная дизъюнктивная нормальная форма.
переменные, статические области памяти, если они включаются в программный контракт (что, правда, противоречит требованиям грамотного, модульного построения интерфейсов), также объявляются "видимыми". В противном случае они рассматриваются как "скрытые". Видимые данные моделируются в манере близкой к их реализации. Скрытые данные могут моделироваться без прямой привязки к реализации. Это позволяет, во-первых, сделать спецификации в большей степени реализационно-независимыми, во-вторых, более абстрактными, и, следовательно, зачастую более короткими и понятными. В моделе-ориентированных спецификациях используются два вида описания функций – эксплицитные (явные) и имплицитные (неявные). Первые – знакомы всем пользователям обычных языков программирования. Такие описания представляют собой описание алгоритма вычисления результата функции. Имплицитный способ состоит в описании ограничений на входные параметры (предусловие) и ограничения на совокупность входных и выходных параметров (постусловие). И пред-, и постусловие – это предикат, то есть функция, результатом которой является булевская величина. Предусловие истинно тогда и только тогда, когда входные параметры входят в область допустимых значений данной функции (поведение функции вне области допустимых значений не определено и поэтому не рассматривается и не тестируется). Постусловие истинно тогда и только тогда, когда совокупность значений входных и выходных параметров удовлетворяет требованиям, задающим функциональность, назначение данной функции. Тем самым, постусловие можно рассматривать как формальное определение критерия правильности полученного результата. Заметим, что имплицитная форма легко позволяет описывать не только конкретное значение, которое должна вычислить функция, но и класс допустимых значений. При описании реальных программных контрактов это очень важно. Рассмотрим два примера. В первом примере не важно, как задавать функцию, в имплицитном или эксплицитном виде. Во втором примере эксплицитная форма практически неприемлема. Первый пример – это функция, которая выполняет некоторые арифметические вычисления над целыми числами. Известна
44 формула (одна из возможных), по которой выполняются данные вычисления, обозначим ее f(x), где x – аргументы. В таком случае эксплицитная спецификация целевой функции tf(x) будет иметь вид (X – тип аргументов; Y – тип результатов) tf : X → Y tf(x) is f(x) Имплицитная спецификация могла бы иметь следующий вид post-tf : X × Y → Boolean post-tf(x, y) is y = f(x) // здесь х – аргумент, // а y – результат целевой функции Заметим, что обе рассмотренные спецификации могут быть реализационно-независимыми, поскольку мы не делаем никаких предположений о том, по какой формуле выполняются вычисления в реализации целевой функции. Важно лишь то, что результат целевой функции должен совпадать с результатом вычисления по формуле f(x). Второй пример: функция, которая выделяет некоторую область памяти, должна возвратить идентификатор этой области. Реализационно-независимая спецификация не может предсказать, какое именно значение примет такой идентификатор. Вместе с тем, в имплицитной форме легко задать ограничение на такой результат. Новый идентификатор не должен совпадать ни с одним из идентификаторов, соответствующих другим областям памяти. Обычно этого требования наряду с требованиями, задающими ограничения типа, достаточно для спецификации такой функции. Возвращаясь к первому примеру, заметим, что если бы аргументом целевой функции были действительные числа, эксплицитную форму без дополнительных соглашений об интерпретации таких спецификаций использовать было нельзя. При спецификации вычислений над действительными числами приходится дополнительно специфицировать точность вычислений и точность представления результатов. Для этих целей имплицитная форма будет предпочтительнее. Например, спецификация функции tf могла бы иметь следующий вид: post-tf : X × Y → Boolean post-tf(x, y) is abs(y-f(x)) < delta Отказ от привязки спецификаций к алгоритмам, используемым в реализации, делает спецификации реализационнонезависимыми лишь формально, а не по существу. От хорошей спецификации, в
сравнении с реализацией, мы ожидаем более явного, прозрачного описания "смысла". Здесь мы касаемся очень тонких материй. Трудно давать строгие определения, позволяющие сравнить два текста с тем, чтобы указать, в каком из них смысл представлен "более явно". Тем не менее, практически всегда оказывается, что "хорошая" спецификация отличается от реализации более абстрактными структурами данных, используемых в описании интерфейсов. В свою очередь можно сказать, что структура данных "более абстрактна" тогда, когда при ее описании мы в большей степени используем такие математические понятия как множества, отображения, графы, их разновидности и т.п. По-видимому, не имеет смысла говорить о том, что математическая нотация и приемы математических описаний, рассуждений, преобразований лучше соответствующих средств, использующихся программистами в их реальной практике. Важно лишь то, что математическая нотация поощряет аналитика (software designer) взглянуть на программу, ее реализацию, ее поведение с некоторых новых для него позиций. Такое рассмотрение программы в новом ракурсе, по-видимому, и является главной причиной, объясняющей плодотворность использования формальных методов даже там, где полностью автоматическое порождение программ из спецификаций и полная аналитическая верификация программ невозможна. KVEST в полной мере использует этот прием описания программных контрактов с использованием абстрактных структур данных. Это относится как к типам видимых данных, так и к описанию скрытых данных. Так при описании арифметических функций, работающих с целыми разной длины, KVEST определяет тип целого бесконечной длины. Этот прием позволяет вскрыть немало ошибок в реализации казалось бы несложных функций. В действительности эти функции не сложны только в классической, "бесконечно-значной" арифметике. Там, где появляется арифметика с конечной длиной целого или беззнаковая арифметика, алгоритмы становятся не очевидными. Сопоставление вычислений, выполненных в "бесконечной" и в "конечной" арифметике позволяет единообразным способом провести верификацию библиотек арифметических операций. В еще большей степени повышение уровня абстракции относится к описанию
45 моделей скрытых данных. Им соответствуют так называемые "абстрактные" переменные. Структура абстрактных переменных может быть совершенно не похожей на структуру скрытых. Более того, состав абстрактных и скрытых переменных, как правило, существенно различается. Единственное требование, исходя из которого выбирается набор абстрактных переменных, – это возможность моделировать поведение целевой системы, ее функций и, тем самым, как минимум, оценивать получаемые от целевых функций результаты. 2.3 Основные понятия Рассмотрим некоторую программную систему, содержащую функционально замкнутый набор процедур. Необходимо определить функциональные спецификации внешних интерфейсов, то есть определить программный контракт, а также разработать тестовые наборы, пригодные для проверки выполнения реализацией программного контракта. Поскольку элементами программного контракта являются процедуры, можно говорить о тестировании программного интерфейса, API. Далее будем считать, что программный интерфейс состоит только из процедур. Существуют и другие виды элементов API, такие как операции, функции, методы (в С++), подпрограммы (в Фортране) и т.д. Будем рассматривать все эти термины как синонимы и использовать для них термин «процедура». Заметим, что речь не идет о тестировании некоторой конкретной реализации программного контракта. Важно построить такую методологию, которая позволяет тестировать поведение программы, не накладывая дополнительных ограничений на внутреннюю структуру реализации. Чтобы подчеркнуть особую важность этого требования, мы называем наши спецификации реализационно независимыми. Дадим несколько определений. Часть тестовой системы, непосредственно участвующую в процессе выполнения тестов и взаимодействия с тестируемой системой (SUT – system under test), будем называть тестовым окружением (test harness). В некоторых случаях вместо SUT мы будем употреблять термин «целевая система». Основную часть тестового окружения составляют так называемые тестовые драйверы (test drivers). Функциональность тестовых драйверов опирается на систему поддержки времени выполнения (test bed). Тестовые драйверы
обычно разрабатываются с учетом специфики целевой системы, тогда как система поддержки времени выполнения независима от целевой системы. Мы различаем два уровня тестовых драйверов. Назовем базовым драйвером тестовый драйвер для некоторой процедуры, который выполняет следующие задачи: • проверяет выполнение предусловия целевой процедуры на некотором наборе входных параметров; • вызывает целевую процедуру с данными входными параметрами и сохраняет полученные значения выходных параметров; • выносит вердикт о корректности работы целевой процедуры; • собирает информацию, необходимую для оценки тестового покрытия, или исследует причины ошибки. Назовем скрипт-драйвером тестовый драйвер для некоторой целевой процедуры или группы процедур, который выполняет следующие задачи: • читает значения параметров тестирования; • генерирует множество входных параметров в соответствии с полученными параметрами тестирования; • вызывает базовый драйвер с некоторым набором входных параметров; • если необходимо, производит дополнительную проверку корректности работы целевой процедуры и выносит вердикт; • если желаемое тестовое покрытие не достигнуто, продолжает генерировать наборы значений входных параметров и вызывать базовые драйверы. Назовем тестовым планом программу, которая определяет порядок вызовов скрипт-драйверов с данными параметрами тестирования, проверяет условия вызова и корректность завершения работы скриптдрайверов. Кроме базовых и скрипт-драйверов и интерпретатора тест-планов тестовое окружение также содержит репозиторий и инструменты для выполнения тест-планов и анализа результатов, хранящихся в репозитории. Репозиторий содержит информацию о всех прогонах тестов, достигнутом тестовом покрытии для различных процедур с различными критериями тестового покрытия и информацию обо всех ситуациях, когда тестовый драйвер вынес вердикт о несоответствии спецификации и
46 реализации. 2.4 Шаги методологии KIL методология состоят из нескольких шагов (см. рис. 1): • определение состава программного контракта; • разработка спецификаций; • генерация тестовых наборов; • выполнение тестов и анализ результатов.
Рис. 1. KVEST методология – шаги и результаты 2.4.1 Определение состава программного контракта Цели этого шага: • определить минимальный и ортогональный интерфейс; • скрыть внутренние структуры данных и детали реализации. Следуя этим целям, мы должны минимизировать ограничения на возможные реализационные решения и знания, необходимые для использования программы, и сделать возможным разработку долгоживущих тестовых для проверки выполнения наборов программного контракта. 2.4.2 Разработка спецификаций Цели: • Строго описать функциональность; • Создать входную информацию для генерации тестов. Базовые драйверы могут быть сгенерированы полностью автоматически. 2.4.3 Генерация тестовых наборов Цели: • сгенерировать тестовые наборы; • дополнить сгенерированные тестовые наборы компонентами, разработанными вручную компонентами (MDC – manually-developed component). Большинство MDC представляют собой конвертеры между модельным и реализационным представлением данных, инициализаторы тестовых структур данных итераторы. Тестовые наборы и
генерируются на основе спецификаций и MDC. После завершения генерации дополнительная модификация тестовых наборов не требуется.
Рис. 2. Общая схема KVEST технологии 2.4.4 Выполнение тестов и анализ результатов К инструментам для пропуска тестов и анализа результатов предъявляются следующие требования: • автоматизация выполнения тестов; • сбор трассировочной информации и вычисление достигнутого тестового покрытия; • предоставление навигационных возможностей; • возможность «инкрементального тестирования», то есть восстановление целевой системы после ошибки или краха и продолжение выполнения тестов с места, где оно было прервано. На рис. 2 обобщенно представлены исходные данные и результаты, которые получаются при использовании KVEST методологии. 2.4.5 Метод тестирования При разработке тестового драйвера необходимо решить три проблемы: • как сгенерировать оракула, то есть программу, которая выносит вердикт о корректности работы целевой процедуры; оценить полноту тестового • как покрытия; • как перебирать комбинации тестовых входных данных. Тестовые оракулы очень похожи на постусловия. Обе функции возвращают логическое значение, имеют те же самые параметры и возвращают истинное значение в том и только в том случае, когда целевая процедура производит корректный результат. Таким образом, генерация оракулов значительно проще, если имеются постусловия. Критерий тестового покрытия – это метрика, определенная в терминах
47 реализации или спецификации. Наиболее известными критериями покрытия в терминах реализации являются: • C1 – все операторы покрыты; • C2 – все ветви покрыты. В случае использования спецификаций для определения критерия покрытия используется так называемый подход тестирования доменов, при котором пространство входных значений разбивается на области. Каждая область соответствует классу эквивалентности. Разбиение может быть выведено из спецификаций, которые описывают ограничения на входные параметры и свойства выходных параметров целевой процедуры, которые явно присутствуют в преди постусловиях формальных имплицитных спецификаций. Таким образом, исходя из имплицитных спецификаций, мы можем успешно решить проблему оценки тестового покрытия. Хорошее покрытие доменов, даже дополненных интересными точками (например, находящимися на границах доменов), не гарантирует хорошего покрытия реализационного кода. Тем не менее, наш опыт показывает, что средний уровень покрытия при KVEST технологии составляет от 70 до 100 процентов операторов реализации. Мы различаем два уровня критериев покрытия. Первый уровень – это покрытие всех ветвей постусловия. Второй – покрытие всех дизъюнктов (элементарных конъюнкций) в постусловии, представленном как СДНФ, также принимая во внимание предусловие. KVEST технология позволяет производить разбиение в терминах ветвей и СДНФ спецификации полностью автоматически. Одна из наиболее сложных проблем – вычисление достижимых дизъюнктов и удаление недостижимых дизъюнктов. В KVEST эта проблема решается путем использования специальных приемов написания предусловий. Наблюдение за достигнутым тестовым покрытием производится скриптдрайверами. Основываясь на этих данных, скрипт-драйвер может подстраивать параметры тестирования и/или длительность тестирования. 2.5 Технология генерации тестов 2.5.1 Классификация API Для начала рассмотрим классификацию API. Классификация определяет выбор способа генерации тестов, применимого к данной процедуре или группе процедур.
Мы рассматриваем пять основных классов API и некоторые расширения этих классов, включающие тестирование параллельного выполнения процедур и тестирование процедур, которые могут вызвать аварийное завершение программы. Эти классы упорядочены – первый класс накладывает самые строгие ограничения на процедуру, а последующие классы постепенно эти ограничения ослабляют: Класс 1. Входные данные могут быть представлены в литеральной (текстуальной) форме, взаимозависимости между параметрами отсутствуют. Такие процедуры могут тестироваться поодиночке, так как для генерации значений входных параметров и анализа результатов не требуются никакие другие целевые процедуры. Примеры взаимозависимостей между параметрами будут приведены ниже. Класс 2. Взаимозависимости между входными параметрами отсутствуют. Однако значения входных параметров не обязательно имеют литеральный вид. Такие процедуры также могут тестироваться поодиночке. Пример: Процедура с указателем в качестве входного параметра. Класс 3. Существуют некоторые взаимозависимости между входными параметрами, однако возможно тестирование отдельной процедуры. Пример: Процедура с двумя параметрами – массив и значение одного из элементов массива. Класс 4. Процедуры не могут тестироваться по отдельности, поскольку значения некоторых входных параметров могут быть получены только в результате вызова других процедур группы и/или результат работы может быть проанализирован только вызовом других процедур. Пример: Процедуры, реализующие операции со стеком, которые получают стек в качестве параметра. Класс 5. Процедуры не могут тестироваться по отдельности. Часть входных и выходных данных скрыта, то есть пользователь не имеет к ним прямого доступа. Пример: объекты классов с закрытым внутренним состоянием, группы процедур, имеющие доступ к переменным, не видимым для пользователя. Расширение классов API для случая параллельного выполнения. Теоретически, процедуры всех классов должны тестироваться параллельно на случай, когда
48 между ними имеется какое-либо взаимодействие. На самом деле, имеет смысл тестировать параллельно только процедуры пятого класса, поскольку они разделяют общие ресурсы и ошибки наиболее вероятны в этом случае. Пример: Процедуры, работающие с почтовыми ящиками (прием и передача сообщений и т.п.) Расширение классов API для случая процедур, которые могут вызвать аварийное завершение программы. Существует специальный класс процедур, для которых аварийное завершение программы является корректной реакцией в некоторых случаях. Пример: Процедура, в которой может произойти деление на нуль, полученный в качестве входного параметра. Если эта процедура не возвращает никакого кода возврата, то нормальной реакцией на ошибку может быть завершение программы. 2.5.2 Схема скрипт-драйвера. Пример API класса 5 Вышеприведенная таксономия является хорошей основой для классификации способов генерации тестов. Для API класса 1 возможна полностью автоматическая генерация тестов. Все остальные классы требуют некоторых дополнительных усилий по созданию MDC. Эти усилия плавно возрастают от класса 2 к классу 5. Специальные расширения классов требуют больших усилий, чем сами классы. Усилия по созданию MDC обусловлены сложностью написания и отладки скриптдрайверов. Ниже мы рассматриваем только одну схему скрипт-драйвера – для API класса 5. Все скрипт-драйверы имеют похожую структуру. Основное различие в пропорции между объемом автоматически сгенерированных и созданных вручную компонент. Скрипт-драйверы класса 1 генерируются полностью автоматически, класса 2 – почти автоматически и т.д. Скрипт-драйвер – это программа, которая составляется и компилируется по KVEST технологии. Общая схема скриптдрайвера определена формальным описанием, которое называется скелетоном. Для каждого класса API имеется свой скелетон. Каждый скрипт-драйвер состоит из деклараций и тела. Декларации генерируются автоматически на основании списка тестируемых процедур и их спецификаций. Тело скрипт-драйвера начинается с разбора параметров тестирования. Эти параметры определяют глубину
тестирования, то есть уровень критерия тестового покрытия и некоторые специфичные данные, такие как интервалы значений, продолжительности тестирования и т.п. До начала тестирования производится инициализация. Например, до начала тестирования процедур записи/чтения файла необходимо этот файл открыть. Такая инициализация пишется вручную. После инициализации начинает работу основная часть скрипт-драйвера. Скрипт-драйвер класса 5 реализует общий алгоритм обхода абстрактного конечного автомата (FSM – Finite State Machine). Цель алгоритма – обойти все состояния автомата и все переходы между состояниями. Состояния конечного автомата соответствуют классам состояний модели исходной подсистемы. Каждый переход соответствует вызову тестируемой процедуры. Алгоритм скрипт-драйвера зависит только от модели исходной подсистемы, не используя никаких деталей реализации, которых нет в спецификации. Наиболее интересный аспект алгоритма скрипт-драйвера состоит в отсутствии явного описания конечного автомата. Прямое описание конечного автомата требует дополнительных усилий, которых по KVEST технологии можно избежать. Существуют попытки построения конечного автомата по имплицитным спецификациям [7]. Однако пока никто не смог предложить полностью автоматического способа такого построения. Вместо явного описания конечного автомата, KVEST использует его косвенное представление. Для описания конечного автомата создатель скрипт-драйвера должен иметь мысленную модель конечного автомата и задать функцию, вычисляющую состояние конечного автомата на основании модельного состояния подсистемы. Рассмотрим более детально алгоритм скрипт-драйвера класса 5. Для примера рассмотрим тестирование группы процедур. Предположим, что мы прошли несколько состояний конечного автомата, то есть несколько раз вызвали целевые процедуры. Теперь мы должны определить следующий переход. Элементарный цикл тестирования состоит из следующих шагов: • Выбираем очередную процедуру из группы.
49 • Вызываем итераторы, которые формируют набор значений входных параметров для этой процедуры. • Если итераторам удалось сформировать новый корректный набор значений, удовлетворяющий предусловию, скрипт-драйвер вызывает соответствующий базовый драйвер с этими параметрами. • Если корректного набора значений сформировать не удалось, возвращаемся к началу и повторяем попытку для следующей процедуры. • После того, как базовый драйвер закончил работу, скрипт-драйвер проверяет вынесенный им вердикт. • Если вердикт положительный (элементарный шаг тестирования закончился успешно), скрипт-драйвер вызывает функцию вычисления очередного состояния конечного автомата, сбрасывает трассировочную информацию об очередном состоянии и переходе и продолжает обходить конечный автомат. 2.5.3 Композиция тестового набора Вернемся к вопросу соединения MDC и автоматически генерируемых компонент. Скрипт-драйверы создаются следуя требованиям соответствующего скелетона. Нам необходимо 5 скелетонов для последовательного тестирования API классов 1-5; один скелетон для параллельного тестирования и пять скелетонов для тестирования процедур, которые могут вызвать аварийное завершение программы. На основе скелетона и спецификаций целевых процедур по KVEST технологии генерируется шаблон скрипт-драйвера. Для класса 1 шаблон представляет собой готовую программу. В шаблонах остальных классов имеются гнезда, заполненные значениями по умолчанию для инициализаторов и итераторов. Если разработчик скрипт-драйвера не нуждается в улучшении содержимого гнезд, шаблон может быть скомпилирован и выполнен. Эта обычная ситуация для класса 2. Для остальных классов разработчик обычно все же должен добавить некоторые итераторы и инициализаторы. В любом случае, для классов 4-5 он должен определить функцию, возвращающую текущее состояние конечного автомата. Базовые драйверы, вызываемые скриптдрайверами, генерируются полностью автоматически. Единственные MDC, вызываемые из базовых драйверов – это
конвертеры данных из модельного представления в реализационное и наоборот. Модельное представление данных отличается от реализационного уровнем абстракции. Например, модели могут использовать «бесконечные» представления целых чисел, множеств, отображений и других структур данных, подходящих для спецификации. Иногда модельное представление очень похоже на реализационное. В этом случае такая трансформация производится по стандартному алгоритму преобразования языка спецификации в язык программирования.
Рис. 3. Схема генерации тестового набора, независимого от целевого языка программирования KVEST использует генераторы тестов, независимые от языка реализации целевой системы. У всех генераторов на входе и выходе текст на языке RSL. Единственные компоненты, которые пишутся на языке реализации – это конвертеры данных. Эти компоненты находятся вне зоны ответственности генераторов тестов. Таким образом, результатом процесса генерации тестов является полный текст тестового набора на языке RSL, который затем транслируется в язык реализации. Чтобы перенести тестовый набор, построенный по KVEST технологии, с одного целевого языка в другой, пользователю необходимо переписать все конвертеры данных и предоставить транслятор с RSL в целевой язык, а также СПВВ. Схема генерации тестов находится на рис. 3. 2.5 Интеграция обратной и прямой инженерии ПО В 1999 году KVEST начинает применяться для совместной работы проектировщиков и верификаторов. Группа разработчиков в Оттаве будет разрабатывать проектную документацию и реализацию, в то время как другая группа в Москве параллельно будет разрабатывать формальные спецификации и тестовые наборы. Такая схема позволяет улучшить
50 качество проектной документации и создать тестовые наборы еще до того, как будет готова реализация. Это один из способов использования KVEST в процессе прямой инженерии ПО. В 1998 году ИСП начал исследовательские работы по генерации документации на естественном языке. Результатом этой работы стал прототип, который демонстрировался на конференции ZUM’98 (Берлин, сентябрь 1998) Этот прототип на основе формальных и неформальных компонентов спецификации синтезирует документацию в стиле UNIX программы man. Результаты демонстрируют реальную возможность генерации документации. Актуальность документации проверяется тестами, которые генерируются из того же источника информации – спецификаций на языке RSL. Работа по расширению генерируемых форм документации и улучшению качества языка продолжается.
3. Современное состояние методов генерации тестов из формальных спецификаций В этом разделе мы будем рассматривать системы, в которых, с одной стороны, в процесс верификации используются формальные спецификации, а с другой предлагается достаточно общая технологическая схема, поскольку реализация теоретического решения отдельных задач сталкивается со значительными трудностями при практическом их применении в процессе верификации индустриального ПО. 3.1 Система ITEX (Interactive TTCN Editor and eXecutor) ITEX [29] – это система для разработки тестов для систем коммуникации. Она включает инструменты TTCN и ASN.1 для анализа и проектирования, тестовый эмулятор и поддержку для генерации полных выполнимых тестовых наборов (ВТН). Основные возможности ITEX: • Тестовый набор состоит из наборов тестовых параметров, заданных в форме таблиц; • ITEX предоставляет набор хорошо интегрированных инструментов для создания и поддержки Абстрактных Тестовых Наборов (АТН), написанных в TTCN; • IETX поддерживает такие фазы разработки тестовых наборов как генерацию наборов тестовых
параметров, редактирование, верификацию и выполнение. Этот набор инструментов хорошо интегрирован с SDT – системой проектирования SDL спецификаций. Тестовые наборы, описанные с помощью TTCN, могут быть преобразованы в форму, которая позволяет тестировать и реализацию на языке программирования и SDL спецификации. Основным недостатком данного подхода в контексте наших исследований является невозможность тестирования API. TTCN не позволяет использовать указатели и другие программные сущности, которые не имеют литерального представления. Кроме того, очень серьезным ограничением SDL-подобных спецификаций является их эксплицитность. Это значит, что довольно легко построить модели и прототипы на основе этих спецификаций, но очень трудно разработать систему ограничений, которая определяет класс возможных реализаций. Имплицитные спецификации решают эту проблему. 3.2 ADL/ADL2 Этот подход [27] наиболее похож на работу нашей группы. Из формальных спецификаций ADL генерирует тестовые оракулы и скелетоны для построения тестовых драйверов и документации. Не очень большое, но интересное отличие состоит в том, что ADL использует не распространенный универсальный язык спецификации, а расширение языков C и C++. В рамках KV проекта на этапе создания прототипа был разработан язык SPP – аналогичное расширение целевого языка. Он документирован в KV Project Report [20]. Аналогичный способ расширения был предложен Барбарой Лисков (B.Liskov) [6]. Существуют идеи расширения Java и других объектноориентированных языков, направленные на разработку ПО по принципу «дизайн по контракту» (design-by-contract) [5, 27, 31]. Однако, несмотря на очевидные преимущества лучшего приема таких языков сообществом разработчиков ПО, до общей концепции еще далеко, общая нотация не выработана. Разницу в результатах KVEST и ADL можно объяснить разницей в классах API, для которых та и другая методологии могут предоставить средства спецификации и генерации тестов. ADL предоставляет инструменты для автоматизации генерации тестов только для процедур, которые могут тестироваться независимо, с параметрами,
51 допускающими независимый перебор. По KVEST классификации это процедуры первого и второго классов. Это значит, что процедуры с зависимыми параметрами, процедуры, которые требуют совместного тестирования, например open/close, или процедуры, которые необходимо тестировать параллельно, например, lock/unlock, или send/receive, отбрасываются. Кроме того, ADL не распознает API класса 1, для которых возможна автоматическая генерация всего тестового набора, включая наборы тестовых параметров и тестовые оракулы. Интересным моментом ADL является возможность генерации документации на естественном языке. Важно, что один и тот же механизм используется для документирования как целевой системы, так и тестовых наборов. Похоже, что авторы ADL сознательно не использовали технологий из области NLG (Natural Language Generation). Это понятно из практических соображений, но не значит, что современные методы генерации текста на естественном языке не могут помочь в генерации программной документации. Возможности KVEST по генерации документации реализованы в прототипной форме. Однако, в противоположность ADL KVEST использует компьютерную грамматику и словарь английского языка для анализа и генерации фрагментов на естественном языке. Это способствует уменьшению числа ошибок в тексте на естественном языке и делает текст более читабельным без дополнительной ручной правки. Значительным преимуществом ADL2 в сравнении с KVEST является возможность спецификации и тестирования классов объектно-ориентированных языков программирования. Этот недостаток KVEST объясняется ограничениями языка спецификации RSL. Расширение KVEST для верификации объектноориентированного программного обеспечения планируется в 1999 году. 3.3 Использование тестовых оракулов, сгенерированных из программной документации Работа [8] является исследовательской и не может рассматриваться как технология, пригодная для промышленного использования. Основной интерес в этом исследовании представляет анализ факторов, которые, по мнению авторов, препятствуют широкому распространению формальных спецификаций для индустриального тестирования
программного обеспечения. Авторы формулируют пять основных проблем, общее решение которых, по их мнению, при существующем положении дел невозможно. Эти пять проблем имеют много общего с набором характеристик, на которых базировалась классификация API в KVEST. Таким образом, Д.Петерс (D. Peters) и Д.Парнас (D.Parnas) и мы пришли к общему пониманию, что это ключевые проблемы в задаче автоматизации тестирования, использующего формальные спецификации. KVEST продолжает исследования в этом направлении и предлагает технологическую схему для частичной автоматизации разработки тестовых наборов для всех классов API. 3.4 Формальный вывод конечного автомата для тестирования класса Эта работа [7] также является исследовательской. В то же время, она представляет интерес, поскольку предлагает схему тестирования группы процедур, аналогично схеме, использующейся в KVEST. В качестве языка спецификации используется Object-Z, а в качестве целевого языка программирования – C++. Задача формулируется следующим образом: построить тестовые наборы для проверки соответствия реализации и спецификации, используя формальные спецификации методов класса. Как критерий тестового покрытия используется объединение двух критериев: покрытие всех классов эквивалентности, которые представляют собой области, полученные в результате анализа разбиений и, затем, проверка результатов на границах и рядом с границами. Авторы этой работы не пытаются решить проблему полностью автоматической генерации тестов. Также они не делают попыток поддержки какихлибо элементов подготовительной фазы с помощью каких-либо инструментов. Однако, все эти шаги описаны очень систематически и могут быть сведены к различным преобразованиям спецификаций. Анализ разбиений и границ производится вручную в соответствии с предложенной авторами методологией. Аналогичным образом строятся спецификации оракулов. Оракул, скомпилированный в C++, вызывает целевую процедуру и проверяет соответствие результатов ее работы спецификации.
52 Наиболее интересна сама схема тестирования, в соответствии с которой динамически генерируются тестовые последовательности вызовов целевых процедур. Генерация контролируется описанием конечного автомата, который представляет абстрактный граф переходов между состояниями тестируемого класса. Авторы описывают методологию построения спецификаций для классов состояний и переходов между ними, одновременно рассматривая проблему исключения недостижимых состояний. Теоретическая слабость этого подхода состоит в отсутствии попыток создания формальной методологии создания спецификации переходов. Очевидно, что при попытках применить этот метод к задачам реальной сложности обнаружатся серьезные проблемы. Понятно, что вывод тестов из спецификаций производится в основном вручную, что ограничивает применимость этого метода в индустрии ПО. Основное отличие KVEST от этой работы состоит в том, что KVEST не требует полного описания конечного автомата, который моделирует состояние целевой системы. Вместо этого KVEST предлагает универсальный алгоритм, который динамически поддерживает доступные состояния и переходы между парами состояний.
4. Заключение и направления дальнейшей работы Опыт KVEST показал, что формальные методы могут использоваться в промышленной разработке ПО. Уровень сложности и размеры приложений KVEST поддерживают этот тезис. Вместе с тем, текущее состояние KVEST и состояние дел в целом диктуют необходимость интенсивного развития подходов, методологий и поддерживающих их инструментов. Можно сформулировать следующие важные проблемы, требующие своего решения: • Пользователи языков программирования не владеют языками спецификаций и формальными методами, это является главным фактором, сдерживающим более широкое использование формальных методов; • Методологии, технологии, CASE системы, поддерживающие разработку ПО, как правило, нацелены на разработку и анализ структур (архитектур) реализаций. Этот подход затрудняет рассмотрение собственно
функциональности ПО. Методологий, которые удачно сочетают преимущества обоих подходов: структурного и функционального, – пока нет; • Статические (чисто формальные) методы анализа программ предоставляют исчерпывающие решения проблем, но применимы лишь для фрагментов реальных систем. Динамические методы типа моделирования или тестирования опираются на некоторые эвристики, поэтому не могут служить базой для исчерпывающего анализа. В связи с этим встает проблема интеграции статических и динамических методов, с тем чтобы извлечь преимущества каждого из них. Для решения этих проблем мы видим следующие пути: • Сближение языков спецификации и языков программирования. Исходя из того, что заставить программиста изучать не только новый для него язык спецификации, но и просто новый язык программирования невозможно, легко прийти к выводу, что надо сделать переход от языка программирования к языку спецификации более незаметным. Попытки сблизить эти языки делались уже давно. Примерами таких языков служат расширение CLU [18], Alphard [19], Eiffel[27, 31], iContract [5], SDL [16], SPP [20]. Некоторые языки, например, Larch [23], предлагают делать это сближение за счет упрощения собственно спецификационной части при одновременном расширении средств для отображения формальной модели в язык реализации. Другие языки, например SDL, пользуясь спецификой проблемной области, заимствуют возможности языков программирования и за счет этого позволяют генерировать исполнимый код прямо из спецификаций. Имеется и вполне удачный опыт встречного движения. Например, авторы ADL путем небольших добавлений расширяют C, C++, Java, и IDL. В результате для пользователя языка программирования нет никаких проблем, по крайней мере, в чтении спецификаций. KVEST в своем перспективном развитии рассматривает как основной последний из перечисленных подходов. В настоящее время разрабатывается версия системы, которая в качестве инструмента специфицирования предлагает средства С++, возможно, пополненные несложным в
53 реализации и в понимании “синтаксическим сахаром”. Заметим, что концепция такого пополнения нуждается в глубокой проработке. Последствия “простых решений” легко видеть на примере ADL. Отсутствие методов и соответствующих средств для повышения уровня абстракции не позволяют пользователям ADL создавать спецификации повышенного уровня абстракции и в достаточной степени автоматизировать генерацию тестов для групп процедур или классов. • Синтез методов анализа и разработки программ, направленных на описание функциональности и на описание структуры реализации. Некоторые аспекты поведения ПО плохо укладываются в рамки рассмотрения API. В качестве примера можно привести стеки телекоммуникационных протоколов и распределенные системы. Такого рода ПО хорошо описывается в форме исполнимых моделей, построенных на основе конечных автоматов, сетей Петри, специальных видов автоматов, например, типа CCS [14]. Общим недостатком таких подходов являются трудности с заданием инвариантов, охватывающие распределенные события. В частности, эта проблема проявилась при попытке обнаружения потенциальных нежелательных взаимовлияний (Feature Interaction). Одним из путей интеграции структурных и функциональных методов являются КА, расширенные описанием ограничений на переходы [4]. Этот подход близок к технике описания и тестирования групп процедур, предложенный в KVEST. Тем самым, KVEST может быть расширен соответствующими средствами для описания протоколов, распределенных систем и других видов ПО, требующих сочетания структурных и функциональных спецификаций. • Интеграция статических и динамических методов в форвард- и реверс-инженерии. Из потенциально возможных приложений синтеза статических и динамических методов разработки/анализа выделим средства для управления уровнем абстракции и генераторы моделей для статического и/или динамического анализа поведения программ. В качестве средств управления уровнем абстракции в KVEST разрабатывается методическая и инструментальная поддержка для “подъема” и “спуска” (“upwarding” and “downwarding”) и средства
трансформации эксплицитных спецификаций в имплицитные (в форме пост-условий). Вплоть до последнего времени эти работы выполнялись полностью вручную. Сейчас разрабатываются некоторые из запроектированных “транформаторов”. Модели, о которых идет речь, являются обобщенным описанием сценариев использования целевой системы. Такие сценарии могут использоваться как для статического анализа (в этом и состоит идея “model checking”), так и для генерации тестовых последовательностей. В KVEST роль таких моделей играли KA в 5-ом виде тестовых драйверов. То, что такой КА разрабатывается вручную, помимо проблем связанных со стоимостью, сроками его разработки, ставит вопрос о соответствии между КА и спецификациями процедур, об отношении критериев тестового покрытия, определенных на основе спецификаций и на основе собственно КА. В настоящее время имеются работы по частичной автоматизации построения такого КА. К сожалению, в них не рассматриваются вопросы, связанные с извлечением КА из спецификаций функций с побочным эффектом. В KVEST делается попытка решить эту задачу на основе использования спецификаций скрытых (абстрактных) состояний целевых систем. Литература 1.
2.
3.
4.
5. 6.
7.
B.Algayres, Y.Lejeune, G.Hugonnet, and F.Hantz. The AVALON project: A VALidation Environment For SDL/ MSC Descriptions. // In: 6th SDL Forum, Darmstadt, 1993. I.Burdonov, V.Ivannikov, A.Kossatchev, G.Kopytov, S.Kuznetsov. The CLOS Project: Towards an Object-Oriented Environment for Application Development. – In Next Generation Information System Technology, Lecture Notes in Computer Science, volume 504, Springer Verlag, 1991, pp. 422-427. I.Burdonov, A.Kossatchev, A.Petrenko, S.Cheng, H.Wong. Formal Specification and Verification of SOS Kernel. // BNR/NORTEL Design Forum, June 1996. Pansy Au and Joanne M. Atlee. Evaluation of a State-Based Model of Feature Interactions. // Proceedings of the Fourth International Workshop on Feature Interactions in Telecommunications Software Systems, June 1997, pp. 153-167. R.Kramer. iContract – The Java Design by Contract Tool. // 4th conference on OO technology and systems (COOTS), 1998. B.Liskov, J.Guttag. Abstraction and Specification in Program Development. – The MIT Press, McGraw-Hill Book Company, 1986. L.Murray, D.Carrington, I.MacColl, J.McDonald, P.Strooper. Formal Derivation of
54 Finite State Machines for Class Testing. // Lecture Notes in Computer Science, volume 1493, pp. 42-59. 8. D.Peters, D.Parnas. Using Test Oracles Generated from Program Documentation. // IEEE Transactions on Software Engineering, 1998, Vol. 24, N. 3, pp.161-173. 9. A.K.Petrenko. Test specification based on trace description. // Software and Programming, New York (translated from Programmirovanie), No. 1, Jan-Feb. 1992, pp. 26-31. 10. A.K.Petrenko. Methods of debugging and monitoring of parallel programs. // Software and Programming, N. 3, 1994. 11. The RAISE Language Group. The RAISE Specification Language. – Prentice Hall Europe, 1992. 12. The RAISE Language Group. The RAISE Development Method. – Prentice Hall Europe, 1995. 13. A.R.Hoare. Communicating Sequential Processes. – Prentice Hall, 1985. 14. R.Milner. Communication and Concurrency. – Prentice Hall, 1989. 15. D. Bjorner et al eds. The Vienna Development Method: The Meta-Language. – Lecture Notes in Computer Science, volume 61, Springer Verlag, 1978. 16. Specification and Design Language. ITU-T recommendation Z100. 17. P.H.J. van Eijk et al eds. The Formal Description Technique LOTOS. – North Holland, 1989. 18. Barbara Liskov et al. CLU Reference Manual. – Lecture Notes in Computer Science, volume 114, Springer Verlag, 1981. 19. Mary Shaw. Abstraction and Verification in Alphard: Defining and Specifying Iteration and Generators. // Communications of the ACM, Vol. 20, N. 8 (August 1977), pp. 553-563. 20. SPP – specification language description. – KV project report, Nortel (Northern Telecom), May 1995. 21. C.A.R.Hoare. An axiomatic basis for programming. // Communications of the ACM, Vol. 12, N. 10 (October 1969), pp. 576-583. 22. C.A.R.Hoare. Proof of correctness of data representations. // Acta Informatica, 1(4): 271281, 1972. 23. J. Guttag et al. The Larch Family of Specification Languages. // IEEE Software, Vol. 2, N. 5, pp. 24-36 (September 1985). 24. А.А.Марков. Теория алгорифмов. // Москва, Изд-во АН СССР, 1954. 25. А.А.Ляпунов. О Логических схемах программ. Проблемы кибернетики, Москва, вып. 1, 1958. 26. Ю.И.Янов. О логических схемах алгоритмов. Проблемы кибернетики, вып. 1, Москва, 1958. Ресурсы сети Internet 27. http://www.eiffel.com/doc/manuals/language/i ntro/ 28. http://www.fme-nl.org/fmadb088.html 29. http://www.kvatro.no/products/itex/itex.htm
30. http://www.sun.com/960201/cover/language.ht ml 31. http://www.elj.com/eiffel/intro/
Формальные методы для ускоренной разработки телекоммуникационного программного обеспечения Н.Н. Мансуров Зав. отделом Инструментальных средств разработки программного обеспечения Институт системного программирования РАН
Аннотация Данная статья обобщает наш опыт разработки инструментальных средств нового поколения, основанных на формальных методах. Целью наших исследований является практическое улучшение процесса разработки программного обеспечения в телекоммуникационном секторе. Мы разрабатываем методику ускоренной разработки программного обеспечения, которая охватывает этапы спецификации, проектирования, тестирования и обратной инженерии. Особенность методики заключается в использовании формальных языков спецификации на ранних этапах разработки и автоматическом восстановлении формальных спецификаций унаследованного телекоммуникационного программного обеспечения. Методика использует наиболее распространенные языки формальных спецификаций, стандартизованные Международным телекоммуникационным союзом (МТС): язык спецификаций и описаний SDL,. язык диаграмм взаимодействия MSC, язык описания тестов TTCN и язык описания данных ASN.1. В данной статье подробно рассматриваются следующие ключевые части методики: • спецификация требований к программному обеспечению в виде сценариев с последующей формализацией на языке диаграмм взаимодействия; • высокопроизводительная валидация требований с использованием моделей на языке SDL; • автоматический синтез SDL моделей по спецификациям на языке диаграмм взаимодействия; • детализация высокоуровневых SDL моделей;
• •
адаптивная генерация программ по SDL моделям; автоматическое восстановление SDL моделей по исходным текстам унаследованного программного обеспечения.
1. Введение В данной статье описываются основные направления научных исследований, выполняемых отделом инструментальных средств разработки программного обеспечения ИСП РАН. Отдел был создан в октябре 1997 года на базе двух групп, которые начиная с 1994 года работали в ИСП РАН над созданием различных инструментальных средств для заказчиков из телекоммукационной промышленности [1]. В настоящее время сотрудники отдела разрабатывают методы обратной инженерии [2,5], создают конкретные системы обратной инженерии (совместно с сотрудниками телекоммуникационной промышленности) [7], а также ведут разработку различных инструментальных средств для языков SDL и MSC [3,4,6,8,9,10,11]. Сотрудники отдела принимают участие в преподавании формальных методов в Московском государственном унивеситете [12,13]. Отдел имеет научно-исследовательские связи с группой TSERG (группа исследования методов разработки телекоммуникационного программного обеспечения) факультета информационных технологий Оттавского Университета, а также выполняет работы по контрактам с компаниями Northern Telecom (Канада) и Telelogic AB (Швеция). Главным направлением научноисследовательской деятельности отдела является: • разработка методики ускоренной разработки телекоммуникационного программного обеспечения, состоящей из набора методов спецификации,
56
•
проектирования, тестирования и обратной инженерии телекоммуникационного программного обеспечения, причем особенностью методики является использование языков формальной спецификации на ранних этапах разработки и автоматическое восстановление формальных спецификаций унаследованного программного обеспечения, а также создание открытой архитектуры, задающей набор формальных языков и инструментальных средств, поддерживающих методику ускоренной разработки и позволяющих масимально ее автоматизировать, делая возможным более широкое внедрение формальных методов в индустриальную практику.
Актуальность нашей исследовательской программы определяется следующими обстоятельствами. Для современной телекоммуникационной промышленности характерны частое обновление технологий, а также сильная конкуренция. В этих условиях решающим фактором коммерческого успеха становится время выхода на рынок [13]. Дополнительные требования более традиционны. Они включают в себя более высокое качество продуктов, лучшее соотношение цена.производительность и более низкие производственные затраты [13,21]. По устоявшемуся мнению, использование формальных методов и соответствующей инструментальной поддержки является важным условием достижения этих целей. Международный телекоммуникационный союз разработал и стандартизовал семейство формальных языков спецификации. К ним относятся язык спецификаций и описаний SDL [14], язык диаграмм взаимодействия MSC [15], язык спецификации тестов TTCN [16], а также язык спецификации данных ASN.1 [17]. Язык SDL является наиболее успешным стандартизованным формальным языком, используемым в телекоммуникационной промышленности. В настоящее время доступны коммерческие инстументальные средства, позволяющие анализировать SDL спецификации, проводить их валидацию используя алгоритмы анализа состояний, автоматически генерировать тесты на языке TTCN по SDL спецификациям, а также автоматически генерировать исполняемые программы для операционных
систем реального времени [18]. Ряд экспериментальных исследований продемонстрировал, что использование CASE-систем на базе языка SDL в промышленных проектах позволяет повышать качество программного обеспечения, снижает стоимость разработки, и, самое главное,позволяет снижать сроки разработки на 20-30%. Наиболее существенные успехи использования языка SDL в телекоммуникационной индустрии связаны с этапами системного проектирования, детального проектирования и автоматической кодогенерации [3,4,6,9,10,11,29], а также с формальной верификацией и тестированием программного обеспечения [19,20]. Вместе с тем, существует ряд барьеров для более широкого внедрения формальных методов в промышленности. По нашему мнению, наиболее существенными из них являются поддержка ранних этапов разработки и поддержка интеграции с унаследованным программным обеспечением. Основной задачей нашего устранение исследования мы видим указанных барьеров. Существует значительный разрыв между математически-ориентированными формальными методами и практикой ранних стадий разработки программного обеспечения [21]. Обычно проектирование новой системы начинается с этапа описания требований, на котором, как правило, делаются серии предварительных неформальных набросков, имеющих целью нащупать правильное решение. Наброски часто переделываются и лишь немногие из них переносятся в проектную документацию. Написание проектной документации становится возможным только после того, как сформировалась концепция будущей системы. На ранних этапах разработки методы формальной спецификации и валидации оказываются практически бесполезными для разработчиков, поскольку требуемый уровень формальности и точности еще не достигнут. В связи с этим, на ранних этапах разработки оказывается возможным формализацизовать только очень абстрактные свойства системы. Цена такой ранней формализации оказывается достаточно высокой, а результаты – слишком незначительные [21]. Напротив, широкое распространение проибретают так называемые сценарные
57 методы проектирования [22,30]. Особенностью сценарных методов является описание требований в виде сценариев использования. Для формализации сценариев могут использоваться диаграммы взаимодействия (MSC) или так называемые диаграммы действий языка UML [30]. Язык диаграмм взаимодействия является особенно привлекательным, поскольку он широко распространен в телекоммуникационном секторе и имеет стандартизованную формальную семантику. Однако в современных коммерческих CASE системах моделирование с использованием языка диаграмм взаимодействий поддерживается недостаточно. Мы считаем, что инструментальная поддержка формальных языков, пригодных для ранних этапов разработки должна привести к значительному ускорению процесса разработки. Основной особенностью разрабатываемой нами методики ускоренной разработки программного обеспечения является использование автоматического синтеза исполняемых SDL спецификаций по MSC спецификациям. Дополнительно, наша методика поддерживает расширения языка диаграмм взаимодействия, предназначенные для описания работы с данными. Синтез осуществляется инструментальным средством, которое мы назвали Московский Синтезатор (MOST-SDL) [8]. Синтезированные SDL спецификации могут быть использованы для валидации требований, а затем постепенно детализированы до уровня исполняемых моделей. Прочие шаги нашей методики включают в себя быструю генерацию тестов по SDL спецификациям и автоматическую генерацию кода по детализированным SDL спецификациям [13]. Помимо поддержки ранних этапов разработки, существует еще одина важная проблема, которая должна быть решена для внедрения CASE-системы, основанных на формальных методах, в промышленную практику. Формальные методы применимы только для таких проектов, в которых программное обеспечение разрабатывается «с нуля». Однако, большинство реальных промышленных проектов используют уже написанное, так называемое унаследованное (базовое) программное обеспечение. Базовое программное обеспечение нуждается в сопровождении, расширении и адаптации к
изменениям в окружении. Новые проекты, как правило, основаны на значительном повторном использовании базового программного обеспечения. Для внедрения формальных методов в промышленности необходимо разработать эффективные методы интеграции компонентов, полученных в среде CASE систем нового поколения и более старых базовых унаследованных компонентов. Унаследованное программное обеспечение обычно разрабатывалось по устаревшим методам. Такие системы часто состоят из смеси высокоуровневого и системного кода, смеси различных языков программирования, архитектур и стилей. Одной из наиболее серьезных проблем, возникающих при использовании унаследованного кода, является отсутствие документации, описывающих проектные решения. До недавнего времени, требование интеграции с унаследованным программным обеспечением являлось барьером для широкого использования формальных методов в промышленности [5]. Для преодоления «барьера унаследованного кода» требуется разработать автоматизированные методы обратной инженерии, которые помогут значительно сократить затраты на восстановление формальных спецификаций базового программного обеспечения. По нашему мнению, эффективные методы восстановления SDL спецификаций унаследованного программного обеспечения сделают возможным достижение следующих целей: • более глубокое понимание работы унаследованных компонентов путем исполнения SDL модели, что дает более интуитивное представление результатов и не требует использования дорогостоящего спецоборудования; • автоматизированная генерация тестов для унаследованного программного обеспечения; • анализ и валидация формальных спецификаций расширений базового программного обеспечения; • анализ взаимодействия расширений; • автоматизированная генерация тестов для расширений; • автоматическая генерация кода для расширений. Автоматически генерируемый код может быть
58 перенацелен на различные целевые языки программирования (например, C, C++,CHILL), а также на работу с различными системами реального времени (например, pSOS, VxWorks и т.д.). В данной статье мы представляем нашу методику так называемого динамического сценарного восстановления спецификаций унаследованного телекоммуникационного программного обеспечения в виде SDL моделей. Наш подход к восстановлению SDL спецификаций включает в себя следующее: • инструментирование унаследованного кода при помощи семантических датчиков, расставляемых в ключевых местах кода, выявляемых на основе статического анализа архитектуры системы; • выбор представительных сценариев из базового набора тестов и других источников; • выполнение сценариев на инструментированной системе и сбор трасс, с последующим переводом трасс на язык диаграмм взаимодействия с состояниями; • синтез SDL моделей по набору диаграмм взаимодействия при помощи московского синтезатора MOST-SDL [5]. Статья имеет следующую организацию. Раздел 2 представляет обзор нашей методики ускоренной разработки программного обеспечения. Разделы 3-6 посвящены вопросам прямой инженерии и описывают применение методики на этапах описания требований, проектирования и тестирования телекоммуникационного программного обеспечения. Раздел 3 описывает вопросы ранней формализации требований, а также методику высокопроизводительной валидации требований с использованием SDL моделей. Раздел 4 описывает центральный компонент нашей методики – автоматический синтез SDL спецификаций по сценариям. Раздел 5 посвящен вопросам детализации синтезированных SDL моделей. Раздел 4 обобщает наш опыт по адаптивной кодогенерации по SDL спецификациям. Раздел 7 описывает наш подход к восстановлению SDL спецификаций унаследованного телекоммуникационного программного обеспечения. В разделе 8 формулируются выводы описываются дальнейших некоторые направления
исследований.
2. Ускоренная разработка телекоммуникационного программного обеспечения В данной статье описывается современная прагматическая методика разработки программного обеспечения, основанная на широко распространенных стандартизованных формальных языках спецификации MSC, SDL и TTCN. Целью нашего исследования является демонстрация того, что современные формальные методы и поддерживающие их CASE-системы могут существенно сократить сроки разработки промышленного телекоммуникационного программного обеспечения и, тем самым, сократить время выхода продуктов на рынок, что является важнейшим определяющим фактором успеха в телекоммуникационном секторе. До недавнего времени, инструментальные системы поддержки разработки (CASEсистемы) не находили широкого применения в промышленных организациях. Однако современные CASE-системы оказываются гораздо более пригодными для работы с крупными промышленными проектами. В данной статье мы описываем методику применения CASE-систем для сокращения времени разработки программного обеспечения.
Рис. 1. Перераспределение времени этапов Многие современные методики разработки программного обеспечения используют принцип удлинения начальных этапов для сокращения общего времени разработки и времени выхода на рынок. На рис. 1 представлено перераспределение времени различных этапов, происходящее в результате применения CASE-систем, поддерживающих формальные методы [13]. Мы утверждает, что увеличение времени начальных этапов до 17%, связанное с построением, валидацией и сопровождением формальной спецификации на SDL и генерации тестов по формальной спецификации может приводить к
59 сокращению общего времени разработки на 30-50% [13]. Известно, что использование формальных методов может приводить к значительному улучшению качества программного обеспечения, что до недавнего времени считалось их главным премуществом. Поэтому основными заказчиками формальных методов выступали секторы промышленности с повышенными требованиями к безопасности программного обеспечения. Однако в данной статье исследуются возможности формальных методов по сокращению времени разработки программного обеспечения, ускорение выхода продукта на рынок. Улучшение качества программ также оказывает прямое влияние на сокращение времени разработки за счет снижения затрат на исправление ошибок и упрощение сопровождения.
Рис. 2. Источники ошибок Значительные сокращения времени разработки могут быть достигнуты за счет снижения затрат на поиск и исправление ошибок в программном обеспечении. По материалам недавних исследований, проведенных университетом Западной Вирджинии и ВВС США [13], источником большинства ошибок являются ранние этапы разработки (см. рис. 2). Причиной 36% ошибок является неправильное истолкование требований, 5% ошибок происходит из-за неполноты требований, 28% ошибок делаются на этапе проектирования. На остальные источники ошибок (взятых вместе) приходится остальные только 31%. С другой стороны, большинство ошибок были обнаружены (и исправлены) на поздних этапах процесса разработки (см. Рис. 3). Так 13,83% ошибок были обнаружены на этапе полетных испытаний, 51,06% ошибок были обнаружены на этапе сборки изделия, 15,96% - на этапе сборки программного обеспечения. Только 9,57% ошибок были обнаружены на
этапе анализа требований.
Рис. 3. Этап обнаружения ошибки Особенностью нашего исследования является преодоление препятствий для внедрения формальных методов на ранних этапах разработки (сбор и описание требований), а также на поздних этапах (сопровождение). На средних этапах разработки наша методика предполагает использование традиционных преимуществ формальных методов. Эти процессы представлены на рис. 4.
Рис. 4. Процессы разработки
Рис. 5. Этапы методики и связи Более подробный обзор нашей методики представлен на рис.5. На этом рисунке показаны этапы методики (справа), ключевые модели (в прямоугольниках), а также наиболее важные обратные связи, обеспечиваемые инструментальными средствами (пунктиры). Зависимости между моделями показаны стрелками. На рисунке опущены зависимости и обратные связи между моделями одного и того же этапа, а
60 также обратные связи между моделями соседних этапов. Мы различаем две различные точки зрения моделирования [22,30,13]: функциональная (слева) и структурная (справа). Структурная точка зрения обычно описывает то, из каких компонентов состоит программа и какие связи имеются между этими компонентами. Функциональная точка зрения описывает то, каким образом компоненты взаимодействуют для обеспечения требуемого поведения. Информационные обратные связи обеспечивают возможность итеративной разработки. По нашему мнению, ускорение процесса разработки должно быть основано на использовании таких итераций. Ключевой особенностью нашего подхода является как можно более раннее использование формальных методов для того, чтобы иметь возможность поддерживать наиболее важные обратные связи и вести на их основе итеративную разработку. Заметим, что в типичном промышленном процессе разработки формализация в лучшем случае начинается с этапа детального проектирования. В случае использования языка SDL системная модель представляется набором SDL блоков, а детальная модель – набором SDL процессов. Переходы к последующим этапам осуществляютсяя вручную, за исключением последнего (перехода от детальной модели к реалиизации). Данный переход частично осуществляется с помощью автоматической кодогенерации. В такой ситуации единственной обратной связью, которую может обеспечить CASE-система, является связь между реализацией и детальной моделью. Остальные обратные связи оказываются практически бесполезными, т.к. соответствующие модели не формализованы, а ручная модификация детальной модели слишком дорогостоящая. Наша методика ускоренной разработки программного обеспечения представляет собой итеративный объектноориентированный процесс, включающий в себя следующие шаги: • описание требований в виде сценариев, формализованных на языкке диаграмм взаимодействия; • высокопроизводительная валидация требований с использованием исполнимых моделей на языке SDL; • синтез моделей требований на языке SDL по сценариям;
• • • •
постепенная детализация моделей требований; адаптивная кодогенерация по SDL спецификациям; высокопроизводительное проектирование тестов ня языке TTCN; автоматизированное восстановление SDL моделей по исходным текстам унаследованной системы.
Рис. 6. Отдельные шаги методики Отдельные шаги методики ускоренной разработки представлены на Рис. 6. Как показано на рисунке, все шаги поддерживаются инструментальными системами для языов SDL, MSC, TTCN.
3. Описание и валидация требований 3.1. Сценарии использования В настоящее время широко распространены методики разработки программ, основанные на концепции сценария использования. Основными понятиями концепции сценария использования являются понятия актора и сценария [22]. Актор представляет собой абстрактную сущность, являющуюся внешней по отношению к разрабатываемой системе. По определению, актор взаимодействует с проектируемой системой для достижения определенных целей. Сценарий представляет собой типичную (иллюстративную) последовательность взаимодействий между одним или несколькими акторами и системой, в результате чего один из акторов достигает одной из своих целей. Такая цель называется целью сценария. Один сценарий может описывать нексолько альтернативных последовательностей событий. За последнее время был разработан целый ряд методик, основанных на концепции сценария
61 [22,25,30,12]. Все методики, основанные на концепции сценария использования, описывают требования к проектируемой системе в виде функциональных сценариев, однако используют различные способы представления сценариев. Согласно [22], отношения между сценариями и акторами представляются на неформальной диаграмме. Сценарии задаются в виде таблиц [12], текста на естественном языке [22], диаграмм действий языка UML [30]. В работе [25] предлагается формализация сценариев на языке диаграмм взаимодействия. 3.2. Высокопроизводительная валидация требований В данном подразделе рассматривается методика валидации требований к программному обеспечению. Валидацией требований называется процесс выявления ошибок в требованиях к проектируемой системе, формулируемых заказчиками. Как было отмечено в разделе 2, обратная связь от реализации к требованиям является решеющей в процессе разработки программного обеспечения. В соответствии с предлагаемой методикой ускоренной разработки (см. рис. 7), валидация требований представляет собой итеративный процесс, состоящий из следующих шагов: 1. Провести формализацию требований в виде сценариев. 2. Создать исполняемую модель требований 3. Создать валидационные сценарии 4. Прогнать валидационные сценарии через модель требований 5. Оценить результирующее поведение модели. При этом возможны два варианта: 5.1. Поведение является допустимым. В этом случае валидационный сценарий может быть добавлен к множеству исходных сценариев. 5.2. Поведение не яявляется допустимым. В этом случае валидационный сценарий отвергается. Эта ситуация означает наличие ошибки или противоречия в требованиях, либо пропущенное требование. Отвергнутый сценарий должен быть преобразован в сценарий использования и добавлен к исходному набору сценариев использования (возможно, после удаления противоречий и т.д.).
6. Проверить условия завершения и, если необходимо, начать новую итерацию с шага 2.
Рис. 7. Валидация требований Введем необходимую терминологию для обсуждения валидационных сценариев. Будем различать первичные сценарии (штатное поведение) и вторичные сценарии (нештатное поведение, исключительные ситуации, коллизии). Все функциональные сценарии являются, по-определению, первичными. Вообще, большинство сценариев, описывающих требования, являются первичными. Под производительностью сценария будем понимать количество ошибок, обнаруженное (или ожидаемое) при выполнении данного сценария. Первичные сценарии обладают низкой производительностью, поскольку они описывают достаточно хорошо изученные ситуации. Напротив, вторичные сценарии являются среднеили высокопроизводительными, поскольку они описывают менее хорошо документированное поведение. Производительность вторичных сценариев оказывается более высокой, поскольку решения проектировщиков в ситуациях, описываемых такими сценариями, могут существенно отличаться от желаний заказчиков либо поведение может оказаться недетерминированным. Наша методика предполагает использование высокопроизводительных сценариев, а также осуществление регулярного контроля покрытия, что позволяет оценивать качество валидации. Высокопроизводительная валидация происходит под управлением риска, когда усилия по валидации сосредотачиваются на компонентах с наибольшим риском. Понятие риска связано с понятием ожидаемой стоимости ошибки. По определению, риск R вычисляется как PF×CF
62 (где PF есть вероятность ошибки; CF стоимость ошибки). Производительность сценария пропорциональна числу ошибок, обнаруженных в результате валидации данного сценариея. С другой стороны, производительность сценария может быть соотнесена с количеством риска, снятого в результате рассмотрения данного сценария. Низкопроизводительный сценарий имеет низкую вероятность обнаружения ошибки, поскольку такие сценарии, как правило, хорошо понятны как заказчикам, так и разработчикам. Напротив, высокопроизводительные сценарии имеют высокую вероятность обнаружения ошибки, в силу того, что они соответствуют вторичным сценариям, т.е. нештатному поведению, обработке аварийных ситуаций и т.п. Обычно, такие сценарии оказываются гораздо менее хорошо изучены разработчиками.
Рис. 8. Классификация сценариев В [13] нами была предложена следующая классификация сценариев по отношению к их производительности (см. рис. 8). Высокопроизводительная валидация может рассматриваться к валидация, управляемая моделью ошибок. Рассмотрение типичных ошибок и типичных областей, связанных с высоким риском, может существенно повышать производительность процесса валидации. Для построения высокопроизводительных сценариев можно построить модель ошибок (на основе некоторой гипотезы об источниках ошибок), а затем выводить сценарии непосредственно на основе такой модели. В случае достаточно полной модели ошибок, критерием покрытия может служить покрытие самой модели ошибок. Важным источником повышения
производительности сценариев является валидация поведения на граничных условиях. Общая стратегия построения высокопроизводительных сценариев заключается в рассмотрении представителей допустимых и недопустимых классов эквивалентности для входных и выходных величин. Одна часть сценариев должна обеспечить общее покрытие допустимых классов эквивалентности, в то время как другая часть должна включать в себя представителей недопустимых классов эквивалентности непосредвтсвенно на границе и вблизи нее. Высокопроизводительная валидация требований к программному обеспечению является разновидностью тестирования, адаптированного для ранних этапов разработки. Большинство рекоммендации относительно тестирования программ применимы применимы и к задаче валидации требований. Валидация не может гарантировать полное отсутствие ошибок. Поскольку исчерпывающее тестирование невозможно по стоимостным соображениям, нужно стремиться максимизировать производительность тестов, т.е. максимизировать количество ошибок обнаруженных набором тестовых сценариев заданного объема. 3.3. Автоматический синтез исполнимых моделей требований на SDL Основу предлагаемой методики ускоренной разработки программ составляет шаг автоматического синтеза исполняемой SDL модели на этапе анализа требований (Рис. 9). Входной информацией для синтеза является сценарная модель, формализованная на языке диаграмм взаимодействия. Единственная структурная информация, присутствующая на данном этапе, состоит из описания множества акторов (представленных отдельными экземплярами на MSC диаграммах). Описание поведения представлено в виде множества частичных функциональных сценариев, описывающих наиболее типичные взаимодействия между внешними акторами и системой. Важная дополнительная информация может быть задана в виде описания потоков данных, передаваемых по сценариям. Для задания этой информации нами были введены специальные расширения языка диаграмм взаимодействия (см. подраздел 4.1.). Так
63 называемая синтезированная модель требований представляет собой одну из возможных проекций информации, формализованной на этапе сбора требований, на этапы детального проектирования и реализации. Это позволяет задействовать все обратные связи, показанные на рис. 9, поскольку информация становится доступной непосредственно по мере составления требований, что позволяет осуществлять итеративную их разработку. Автоматический синтез исполняемы моделей требований на языке SDL по MSC спецификациям обладает следующими преимуществами: • путем исполнения валидационных сценариев на SDL модели становится возможной высокопроизводительная валидация требований; • MSC спецификации могут разрабатываться независимыми группами специалистов, поскольку архитектурная целостность системы будет автоматически обеспечиваться при синтезе; • автоматический синтез снимает необходимость в регрессионном тестировании, поскольку сценарии, признанные допустимыми, добавляются к набору валидационных сценарием и используются на следующих итерациях как входная информация для синтеза; • синтезатор позволяет производить раннее обнаружение определенных классов ошибок; • синтез позволяет исследовать различные правила композиции сценариев (последовательная композиция, параллельная композиция и т.д.); • MSC модели обладают высокой модельностью, поэтому они гораздо более предпочтительны в сопровождении, обладают высоким потенциалом для повторного использования. Синтезированная модель требований может быть использована для генерации дополнительных сценариев, которые оказываются длиннее исходных валидационных сценариев и, тем самым, имеют большую ценность для валидации [27]. Исполнение синтезированной модели требований позволяет быстро обнаруживать неполноту исходных требований и противоречия в требованиях. Это происходит благодаря тому, что дополнительные
сгенерированные валидационные сценарии осуществляют значительную вариацию поведения, включая нештатные ситуации. Такие сценарии оказываются более производительными, по сравнению с исходными. Синтезированная модель требований на языке SDL может быть использована для автоматической генерации тестов на языке TTCN [19,20].
4. Синтез SDL спецификаций по сценариям В данном разделе будут описаны детали автоматического синтеза SDL моделей по сценариям, формализованным на языке диаграмм взаимодействия. Будут рассмотрены вопросы формализации сценариев, расширения языка диаграмм взаимодействия для описания обработки данных, ключевые понятия, используемые алгоритмом синтеза. Описание алгоритма синтеза будет проиллюстрировано небольшим примером. Особенности нашего подхода включают в себя следующее: • формализация сценариев использования при помощи диаграмм взаимодействия высокого уровня (HMSC); • генерация конечных автоматов по сценариям; • спецификация потоков данных внутри сценариев с использований специальных расширений языка диаграмм взаимодействия; • автоматический синтез моделей на языке SDL. 4.1. Формализация сценариев на языке диаграмм взаимодействия Наш подход к формализации сценариев основывается на следующих принципах: • каждый сценарий формализуется на так называемой базовой диаграмме взаимодействия (bMSC) [15]; • связи по управлению между сценариями формализуются припомощи диаграмм взаимодействия ввысокого уровня HighLevel MSCs (HMSC) [15]. Связи по управлению между сценариями включают в себя альтернативные части сценариев, повторяющиеся части сценариев, а также отношение использования и отношение расширения одного сценария другим [22];
64 •
связи по данным между сценариями формализуются при помощи наших расширений языка даиграмм взаимодействия [8]; • используется определенное правило композиции сценариев [8]: Последовательная композиция сценариев (внешний актор выбирает некоторый сценарий, который затем выполняется до полного завершения) Параллельная композиция (одновременно могут выполняться несколько различных сценариев) Множественная композиция (одновремено выполняются несколько экземпляров одного и того же сценария для разных акторов) Для формализации сценраиев используется расширенный язык диаграмм взаимодействия [15]. Каждый сценарий формализуется диаграммой взаимодействия высокого уровня, описывающей связи по управлению между сценариями. Специальные расширения языка диаграмм взаимодействия описывают потоки данных внутри сценариев (так называемые локальные потоки данных), а также потоки данных между различными сценариями (так называемые глобальные потоки данных). Рассмотрим наши расширения более подробно [8]. 1. Определения переменных. Допускаются определения переменных различных типов. Семантика звимствована из языка SDL. Графически, определение переменной задается в текстовом символе на любой диаграмме. По построенияю, локальная копия этой переменной будет присутствовать в каждом процессе. При определении переменных используется следующий упрощенный синтаксис языка SDL: dcl ;
::=
2. Действия. В символах действия диаграмм
мы допускаем использование операций над локальными переменными. Семантика операций наж переменными заимствуется из языка SDL. При определении переменных используется следующий упрощенный синтаксис языка SDL: ::= := <expr> ::= (<expr1>,…,<exprn>)
3. Параметры сообщений. Мы допускаем использование параметров соощений. Синтаксически, в качестве параметров сообщений допускаются только имена переменных. Семантика параметров сообщений заимствуется из языка SDL. 4. Параметры создания процессов. Акторы могут передавать параметры при создании экземпляров процессов. В качестве параметров при создании процессов могут использоваться только имена переменных. Семантика параметров сообщений заимствована из языка SDL. 5. Локальные состояния. Существенным расширением языка диаграмм взаимодействия является использование локальных состояний, связанных с проверкой значений локальных переменных. Графически, локальные проверки задаются локальным состоянием, к которому присоединен дополнительный комментарий, содержащий булевское выражение.. Семантика локального состояния таковы, что все последующие события выполняются только тогда, когда условие, указанное при состоянии, является истинным. Синтаксически, выражения, участвующие в локальных состояниях, могут иметь следующий вид:
expression> ::= |
Альтернативные последовательности событий могут быть заданы на другой диаграмме после локального состояния с тем же именем, но другим выражением. Все выражения в локальном состоянии с одним и тем же именем, должны быть взаимно-исключающими. 6. Таймеры. Последовательность событий set и timeout на диаграммы взаимодействия может быть использована для задержки во времени выполнения сценария. При нештатном выполнении сценария такая задержка может приводить к ошибке. Таймеры с параметрами не поддерживаются. Понятие потоков данных через сценарии проиллюстрировано на рис. 10 и рис. 11. На рис. 10 приведены два локальных потока данных через сценарий abc are shown (пунктирные линии). Первый поток включает в себя следующие события: a: in x(p,q) from env; a: create b(p,q); b: out w(r) to env;
65 Заметим, что объекты B и C используют различные (локальные) копии переменной r. Таким образом, параметр сообщения, посылаемый объектом B в не обязательно равен p+1.
Рис. 10. Потоки данных через сценарий (1) Второй поток данных включает в себя следующие события: a: in x(p,q) from env; a: create b(p,q); b: out y(p) to c; c: in y(p) from b; c: action ‘r:=p+1’; c: out z(r) to env.
Рис. 11. Потоки данных через сценарий (2) Отметим, что объект C посылает сообщение z(r) в окружение только при условии, что значение выражения r>0 истинно. Для экземпляра C альтернативные последовательности событий могут быть заданы на других диаграмах при помощи локального условия с тем же именем и новым выражением. В случеа, если альтернативная последовательность включает в себя взаимодествие с другими экземплярами, необходимо использовать глобальное состояние. На рис. 11 приведен пример глобального потока данных между различными сценариями. На рис. 11 параметры сообщения value возвращаемые сценарием pop в качестве реакции на сообщение get зависят от событий в сценарии push. Подразумевается, что операции push и pop представляют собой процедуры на языке SDL, реализующие сообтветствующие стековые операции.
Основное назначение расширений языка диаграмм взаимодействия по работе с данными состоит в том, чтобы обеспечить возможность более точного определения функциональных требований на этапе сбора и анализа требований. Вместе с тем, те же самые расширения превращают язык диаграмм взаимодействия в мощное средство проектирования, пригодное для использования на более поздних этапах разработки (крупноблочное проектирование и детаьное проектирование). 4.2. Алгоритм синтеза Алгоритм синтеза состоит из следующих шагов [8]: 1. интеграция HMSC модели; 2. построение MSC срезов; 3. детерминизация MSC срезов; 4. минимизация MSC срезов; 5. генерация SDL поведения; 6. генерация SDL структуры. Ключевым понятием алгоритма синтеза является понятие событийного автомата. Событийный автомат представляет собой конечный автомат, соответствующий единственному объекту диаграммы взаимодействия, так что входными символами автомата являются события данного объекта. Мы различаем три типа MSC событий: входные события, активные события и пустое событие. • Пустое событие представляет собой вырожденное событие, добавленное для упрощения описания алгоритма синтеза. • Входные события (требуют синхронизации с другими объектами, решение принимается другим объектом) Прием сообщения in( i,m ) Срабатывание таймера timeout( t ). • Активные события (не требуют синхронизации с другими объектами, решения принимаются локально данным объектом) Посылка сообщения out( i,m ) Действие action( a ) Установка таймера set( t,d ) Сброс таймера reset( t ) Остановка stop Локальное условие check( c ). Наш алгоритм синтеза осуществляет построение событийных автоматов специального вида, так называемые MSC срезы. По определению, MSC срез (по данному объекту) представляет собой событийный автомат, генерирующий все
66 трассы событий для данного объекта. Для построения MSC среза используется следующий алгоритм: 1. начальные состояния событийного автомата совпадают с символами HMSC графа; все переходы событийного автомата помечены пустыми событиями; 2. для каждого базового MSC строится цепочка состояний, соответствующая последовательности событий для объекта, по которому производится срез; 3. каждая ссылка на базовую MSC из HMSC графа заменяется на цепочку состояний для этой базовой MSC; 4. стартовое состояние событийного автомата соответствует стартовому символу HMSC. Иллюстрация работы алгоритма приведена на Рис. 13. 4.3. Пример Проиллюстрируем работу алгоритма синтеза на небольшом примере, приведенном на рис. 12. MSC модель на рис. 12 состоит из двух сценариев Wait and Reply. Мы используем правило последовательной композиции. Объект R (получатель) соответствует системному актору, объект S (отправитель) соответствует внешнему актору.
для объекта S на диаграмме MSC wait. Данный автомат состоит из единственного перехода, помеченного активным событием out(x,r). На третьем шаге алгоритма, построенный автомат замещает соответствующий переход в начальном автомате. Следующие два шага обновляют начальный автомат на основе информации из диаграммы MSC reply для объекта S. Окончательный MSC срез для объекта S представлен в правом нижнем углу рис. 13.
Рис. 13. Отдельные шаги алгоритма
Рис. 14. Дальнейшие шаги алгоритма синтеза Рис. 12. Пример работы алгоритма синтеза Отправитель S является инициатором обоих сценариев. Сценарий wait начинается с посылки объектом S сообщения X. Согласно данному сценарию, объект получатель R должен в этом случае «заснуть» на некоторый интервал времени. Сценарий reply начинается с посылки объектомотправителем S сообщения Y. Согласно данному сценарию, объект-получатель R должен послать сообщениеW. На Рис. 13 показаны отдельные шаги алгоритма построения MSC среза для объекта. Первый шаг алгоритма строит начальный событийный автомат по HMSC графу. Затем, строится событийный автомат
Рис. 15. Сгенерированная структура на языке SDL для примера на рис. 12 Рис. 14 показывает дальнейшие шаги алгоритма синтеза. Недетерминированный MSC срез для объекта S детерминизируется (с
67 смысле событийных автоматов) и минимизируется. На основе полученного событийного автомата DEA S генерируется SDL граф, описывающий поведение соответствующего SDL процесса. Рис. 15 показывает сгенерированную структуру на языке SDL для примера на рис. 12.
5. Сборка и валидация архитектуры В данном разделе рассматриваются некоторые вопросы поддержки детализации моделей требований на языке SDL и доведение их до проектных моделей.
Рис. 16. Этап системного анализа Методика ускоренной разработки программного обеспечения предполагает использование автоматического синтеза SDL спецификаций по сценариям на этапе системного анализа. На данном этапе происходит определение архитектуры проектируемой системы и разработка сценариев для каждого архитектурного компонента (рис. 16). Входная информация на данном этапе представлена в виде набора так называемых системных сценариев. Обычно, системный сценарий является проекцией некоторого сценария использования системы, построенного на этапе анализа требований. Структурная информация, присутствующая в системных сценариях, состоит из множества внешних акторов и множества архитектурных компонентов (представленных как отдельные объекты на диаграммах взаимодействия). Функциональная информация представлена в виде сценариев типичного взаимодействия между внешними акторами и архитектурными компонентами, а так же между компонентами, при этом цель системного сценария остается такой же, как в
соответствующем исходном сценарии. Дополнительная функциональная информация может быть представлена в виде потоков данных по системным сценариям. По этой информации может быть синтезирована так называемая синтетическая архитектурная модель (САМ). Валидация синтетической архитектурной модели обеспечивает своевременную обратную связь как для разработчиков системных сценариев, так и для разработчиков архитектурной модели (рис. 16).
Рис. 17. Детализация архитектурной модели В соответствии с алгоритмом синтеза, синтезированная архитектурная модель будет воспроизводить архитектурные компоненты, присутствующие в сценариях, синтезировать поведение каждого архитектурного компонента по всем имеющимся системным сценариям, и интегрировать модель в единое целое. Автоматически восстановленные связи между компонентами можно сравнить с предполагаемыми (описанными в архитектурной модели). Опыт использования синтезированных архитектурных моделей показывает, что они оказываются полезны для выявления дефектов этапа системного анализа. Описанный в данном разделе шаг метоики является прямым продолжением валидации требований. Следующим шагом должна стать постепенная детализация синтезированной архитектурной модели, наполнение ее последующими проектными решениями (рис. 17). В качестве одного из способов детализации можно использовать вертикальную декомпозицию исходных MSC моделей (рис. 18). В сценарии reply из примера на рис. 12 объект R представлен в виде набора из трех объектов нижнего уровня: R1, R2, R3. Потоки сообщений между
68 объектами нижнего уровня на диаграмме декомпозиции должны быть совместимы с потоками сообщений на родительской диаграмме. Диаграмма декомпозиции задает два варианта поведения, которые не были наблюдаемы на родительской диаграмме. Альтернативы задаются при помощи состояния с одним и тем же именем. Синтезированная архитектурная модель для данного примера приведена на рис. 19
используется в большинстве коммерческих SDL CASE-систем для исполнения, валидации и генерации тестов. Некоторые SDL системы используют сгенерированный код для оценки производительности системы. Вместе с тем, наибольшее преимущество, связанное с автоматической генерацией кода, заключается в возможности использования сгенерированного кода непосредственно в продуктах [3,29]. Однако, большинство промышленных проектов избегают использование существующих кодогенераторов на этапе реализации [20].
Рис. 18. Вертикальная декомпозиция Рис. 20. Основные преобразования при генерации кода по SDL спецификациям
Рис. 19. Синтезированная архитектурная модель
6. Адаптивная генерация кода по SDL спецификациям В данном разделе мы описываем наш опыт разработки генераторов кода для языка SDL для промышленного использования [1,3,4,6,9,10,11,31]. В начале раздела мы ставим проблему адаптации сгенерированного кода. Затем мы сравниваем несколько подходов к адаптивной генерации кода и перечисляем основные препятствия, затрудняющие адаптацию сгенерированного кода. Затем мы описываем понятие декларативных отображений [11,31] как одну из перспективных возможностей для генерации адаптивного кода. Автоматическая генерация кода по SDL спецификациям является гораздо более распространенной, чем может показаться на первый взгляд. Сгенерированыый код
Рис. 20 представляет основные преобразования производимые при генерации кода по SDL спецификациям. Использование сгенерированного кода в промышленных проектах сталкивается в целым рядом трудностей [3,29]: • использование необходимого целевого языка кодогенерации (CHILL, C, C++, Java, и т.д.); • качество сгенерированного кода [6,10,11]: размер сгенерированного кода, эффективность сгенерированного кода, читабельность сгенерированного кода; • программные интерфейсы к сгенерированному коду [3]; • интегрирование сгенерированного кода с унаследованным кодом; • непосредственное использование кодовых вставок на целевом языке в сгенерированном коде [3]; • использование различных отображений для разных частей системы (оптимизации); • сборки и интеграция системы, использующей сгенированный код. Наш опыт разработки кодогенераторов
69 для промышленных проектов сдидетельствует о том, что каждый проект выдвигает уникальные требования к сгенерированному коду. Это означает, кодогенератор и сгенерированный кода должны обладать свойством адаптивности к требованиям конкретного проекта, кодогенератор должен позволять изменять решения о структуре и поведении сгенерированного кода. Согласно [3] идеальной является ситуация, когда кодогенератор является дополнительным «сотрудником» проекта, т.е. полностью вписывается в требования конкретного проекта. В настоящее время несколько исследовательских групп ведут разработку различных аспектов адаптивной кодогенерации. Существующие подходы к адаптивной кодогенерации включают в себя следующее: • система поддержки этапа выполнения (библиотека или объектноориентированный каркас); • использование макросов в сгенерированной коде; • настраиваемый кодогенератор; • поддержка кодовых вставок в спецкомментариях; • аннотации этапа кодогенерации; • декларативные отображения.
Рис. 21. Адаптация сгенерированного кода может осуществляться на различных этапах Основной трудностью кодогенерации является разработка соответствующего отображения [6,11]. Отображением называется согласованный набор решений по представлению исполняемых и структурных конструкций исходного языка, таких что результирующая программа на целевом языке кодогенерации оказывается синтаксически и семантически правильной с точки зрения целевого языка. Существует целый ряд проблем, связанных с отображениями,
которые существенно сокращают пространство проектных решений при разработке адаптивного кодогенератора: Исполняемые конструкции исходного языка достаточно часто имеют семантически близкие эквиваленты в целевом языке, что позволяет отображать их напрямую в эти конструкции (например, циклы, условные выражения, присваивания и т.д.). • Семантически далекие исполняемые конструкции исходного языка могут быть смоделированы группами исполняемых конструкций целевого языка (возможно с использованием некоторых структурных конструкций). Часто такие группы могут быть инкапсулированы в библиотеку поддержки этапа выполнения. • Некоторые структурные конструкции могут быть представлены семантически близкими эквивалентами (например, объекты, процедуры модули, пакеты и т.д.) • Некоторые структурные конструкции требуют глубокой трансформации во время трансляционных преобразований, выполняемых при кодогенерации (что может существенно снижать возможности последующей адаптации • Большинство структурных конструкций могут быть проинтерпретированы на этапе исполнения (что существенно неэффективно). • Некоторые структурные конструкции могут быть представлены группами структурных (а также с добавлением некоторого количества исполнимых) конструкций, однако это незбежно приводит к явлению фрагментации сгенерированного кода [6] и отрицательно сказывается на адаптации сгенрированного кода. Следующие факторы снижают возможность адаптации сгенрированного кода: • решения, связанные с отображением исходного языка в целевой, не локализованы; • решения, связанные с отображением, сильно взаимосвязаны; • пространство возможных отображений оказывается весьма разреженным из-за семантических и синтаксических ограничений целевого языка (несмотря на то, что для каждой отдельно взатой
70 конструкции исходного языка может существовать несколько вариантов отображения в целевой язык); • решения, связанные с отображением, как правило, невозможно изменять на более поздних этапах преобразований, составляющих процесс кодогенерации.
Рис. 22. отображений
Концепция
декларативных
В [6,11] нами была предложена концепция декларативных отображений как перспективное направление генерации адаптивного кода по SDL спецификаций (рис. 22). Следующие особенности составляют определение декларативного отображения: • решения относительно представления структурных конструкций исходного языка откладываются на самый поздний из возможных этапов, т.е. на этап исполнения сгенерированной программы; • сгенерированный код содержит «декларации», представляющие собой непроцедурные указания того, какие конструкции исходного языка используются в конкретной программе; • «декларации» исполняются на так называемом этапе раскрутки сгенерированной программы (являющегося начальной стадией этапа исполнения; • поддержка этапа раскрутки представляет собой библиотеку, которая определяет то, какие структуры данных этапа исполнения будут построены для каждой из конструкций исходного языка; • системы поддержки этапа исполнения представляет собой каркас для сгенерированных «исполнимых» конструкций и структур данных, построенных на этапе раскрутки. Автоматическая генерация кода по SDL спецификациям является очевидным способом ускорения разработки
программного обеспечения. Однако, как было продемонстрировано выше, требуются значительные усилия для обеспечения интеграции сгенерированного кода с остальными частями окончательной программной системы в реальных промышленных проектах. Мы считаем, что разработка адаптивных кодогенераторов является весьма актуальной для более широкого внедрения автоматической кодогенерации. По нашему опыту, не существует простых и универсальных решений задачи адаптивной кодогенерации. Скорее всего, успешной окажется комбинация подходов, описанных в данном разделе, включая концепцию декларативных отображений.
7. Восстановление SDL спецификаций по исходным текстам унаследованных систем CASE-системы нового поколения, использующие SDL, приводят к значительным улучшениям качества процесса разработки программного обеспечения, производительности труда и времени выхода окончательного продекта на рынок. Однако для более широкого внедрения CASE-систем в телекоммуникационном секторе необходимо разработать эффективные методы интеграции компонентов, производимых автоматизированно, с уже существующими, так называемыми унаследованными компонентами. Обычно, унаследованное базовое программное обеспечение разрабатывалось с применением смеси различных языков высокого и низкого уровней, различных архитерктур и стилей. Особенностью унаследованных систем является плохая документированность проектных решений. До недавнего времени, все жто составляло существенный «барьер» для внедрения формальных методов [5,13]. Для преодоления «барьера» унаследованного кода необходимо разрабатывать автоматические методы восстановления формальных спецификаций по исходным текстам программ. Наличие эффективных методов восстановления SDL моделей позволит достичь следующие цели: • понимание структуры и поведения унаследованного программного обеспечения. Известно, что исполнение SDL модели дает весьма наглядные
71
• •
•
•
результаты и не требует использования дорогостоящего спецоборудования (рис. 23); автоматизированная генерация тестов для унаследованного программного обеспечения (рис. 23); анализ и валидация формальных спецификаций нового программного обеспечения, разрабатываемого на базовой платформе (возможно, с использование формальных методов) (рис. 24); автоматическая генерация тестов для нового программного обеспечения, разрабатываемого на базовой платформе (рис. 24); автоматическая генерация кода для нового программного (рис. 24). Для интеграции генерированного кода с унаследованными компонентами требуется использование адаптивных кодогенераторов (разд. 6).
Рис. 23. Унаследованное программное обеспечение
Рис. 24. Новое программное обеспечение В данной статье описывается методика динамического восстановления формальных SDL спецификаций унаследованного телекоммуникационного программного обеспечения по сценариям. Особенности нашего подхода состоят в следующем:
• установка семантических датчиков [5] в исходные тексты унаследованных компонентов в соответствии с некоторой стратерией инструментирования, выработанной на основе архитектурного анализа кода; • выбор представительных сценариев из регрессионных тестов и других источников; • исполнение сценариев на инструментированном коде унаследованной системы с последующей генерацией трасс в формате MSC; • синтез SDL спецификации с использованием Московского Синтезатора по набору MSC [8]. Этот процесс повторяется до тех пор, пока восстановленная SDL спецификация не станет удовлетворять определенным критериям [5]. Полученная SDL модель используется для оценки и улучшения покрытия набора регрессионных тестов. 7.1 Обзор методики восстановления Динамический подход к восстановлению SDL спецификации унаследованного компонента по сценариям представляет собой процесс синтеза модели по трассам, получаемых за счет исполнения инструментированной системы (Рис. 25). Исполнение системы управляется набором унаследованных тестов [5]. Автоматический синтез SDL спецификаций по MSC является ключевой технологией предлагаемого динамического подхода к восстановлению спецификаций. В предыдущих разделах статьи, синтез SDL по MSC рассматривался исключительно как техника прамой инженерии. В динамическом подходе мы используем двойственность нотации MSC, пригодной как для для описания требований, так и для описания трасс. Альтернативным подходом в восстановлению SDL спецификаций является так называемый прямой подход [2,5]. Сравнение подходов приводится на Рис. 25. Прямое восстановление спецификаций происходит непосредственно за счет проведения некоторого семантически корректного трансляционного преобразования [2]. Интересный подход к восстановлению спецификаций представлен в [21]. Мы называем жтот подход частичным восстановлением. При частичном
72 восстановлении выполняется выборочное преобразование управляетмое так называемой картой предолжений исходной программы (рис. 25). Записи в карте состояний содержат все предолжения из исходной программы (в некоторой канонической форме. В катре предолжений вручную задается правило перевода всех вхождений предложений данного типа. Каркас модели восстанавливается автоматически.
Рис. 25. Выборочное преобразование
Рис. 26. Обзор методики восстановления Описываемый подход к восстановлению SDL спецификаций представляет собой итеративный процесс, состоящий их следующих четырех этапов: 1. подготовка; 2. динамический сбор трасс; 3. синтез SDL модели; 4. исследование SDL модели.
Каждый этап состоит из нескольких шагов. Итерации осуществляются под упраавлением критериев завершения, проверяемых на последнем этапе. Обзор методики восстановления представлен на рис. 26. 7.3 Детальное описание методики восстановления 7.3.1. Фаза подготовки Целью данного этапа является разработка стратегии установки датчиков и выбор набора сценариев, под управлением которых будет выполняться проинструментированная система. Шаг 1. Анализ кода. Целью данного шага является определение стратегии установки датчиков. На данном шаге применяются известные методы статического структурного анализа. Две модели унаследованного компонента оказываются полезными для определения датчиков – архитектурная модель системы (основные компоненты и их связи) и граф вызовов системы [7]. Граф вызовов системы должен показывать внешние интерфейсы системы (обычно – системные вызовы или ассемблерные вставки). Шаг 2. Выбор точки зрения моделирования. Динамический подход к восстановлению спецификаций может применяться для обратной инжеенрии и генерации тестов исходя из трех различных точек зрения: «черный ящик» (окружение), «белый ящик» (базовый код) или «серый ящик» (взаимодействие подсистем). Точка зрения моделирования существенным образом овлияет на структуру получаемой SDL модели. Она также влияет на уровень детализации трасс и, тем самым, на объем работы по адаптации автоматически сгенерированных тестов [19] (см. также шаг 11). Шаг 3. Выбор критерия покрытия и набора датчиков. На данном шаге окончательно определяется стратегий установки датчиков в исходный текст системы (определяются конкретные места в исходном коде, куда будут установлены датчики и определеляется формат выдачи каждого датчика). Стратегия установки датчиков в большой степени определяется критерием покрытия. Внешний интерфейс трассируемой части системы определяется в терминах точек на архитектурной модели и графе вызовов таким образом, что датчики
73 регистрируют прохождение информации через выбранную границу и записывают ее в желаемом формате. Шаг 4. Выбор первичных сценариев. Динамическое исполнение системы и сбор трасс управляется некоторым набором тестов. Мы предлагаем использовать для первой итерации (унаследованный) набор регрессионных тестов Итеративный процесс должен начинаться с регрессионных тестов. Такие тесты обычно представляют из себя смесь тестов сертификации (обычно только штатное поведение, низкая производительность), первичных сценариев (низкая производительность) и некоторых наиболее важных вторичных сценариев (средняя или высокая производительность). На последующих итерациях для улучшения покрытия добавляются новые функциональные сценарии. По мере совершенствования модели, она может быть использована для автоматической генерации тестов на языке TTCN согласно методикам, хорошо известным по литературе [19,20]. На данной фазе процесса мы становимся больше заинтересованы в новых вторичных, высокопроизводительных сценариях. Производительность сценариев обсуждалась в разд. 3. 7.3.2 Получение трасс Целью данного этапа является получение набора трасс, соответствующих выбранной стратегии установки датчиков и выбранному набору сценариев. Шаг 5. Инструментирование системы. Для выполнения данного шага требуется создать инфраструктуру, позволяющую проводить инструментирование и исполнение унаследованной системы. Датчики должны устанавливаться в соответствии с выбранной стратегией установки датчиков. Идеальной является ситуация, когда инструментирование выполняется автоматически. Шаг 6. Запуск инструментированного кода. Задачей данного шага является сборка и запуск проинструментированной унаследованной системы. Для исполнения системы может быть использовано целевое спецоборудование или его эмуляторы. Результатом шага является набор трасс. Дополнительным результатом данного шага является информация о покрытии системы выбранными сценариями.
7.3.3 Синтез SDL модели
Даный этап является ключевым для нашего динамического подхода. Целью этапа является синтез SDL модели. Шаг 7. Перевод трасс в формат MSC. Данный шаг был введен в методику для разделения двух задач: динамического сбора трасс по унаследованному коду и синтеза SDL моделей по сценариям. Задачей данного шага является простое преобразование трасс в снтаксис языка диагармм взаимодействия. Данный шаг определяется различиями между форматом трасс (выбираемый на шаге инструментирования) и форматом MSC, поддерживаемого Московским Синтезатором. Шаг 8. Введение состояний в MSC. Данный шаг выполняет процесс «абстакции» представленный на Рис. 26. Целью шага является выявление последовательностей обменов сообщениями соответствующих транзакциям в сценариях использования. На основе этой информации линейные диагарммы взаимодействия, соответствующие трассам, преобразуются в MSC модель. Сущность данного преобразования заключается во введении состояний в те точки трасс, где возможны повторы или альтернативы. Введение состояний «обогащает» входные MSC модели, что позволяет синтезировать более интересные SDL модели. Шаг 9. Синтез SDL моделей. Данный шаг выполняется автоматически Московским Синтезатором (MOST-SDL) [5]. Техника синтеза была описана в разделе 4. Результатами данного шага являются: 1) синтезированная SDL модель и 2) некоторые метрики сложности синтезированной модели – число состояний в модели и метрика недетерминированности синтезированной модели. Последняя используется как неявный критерий завершения итераций процесса восстановления спецификации. Смысл данной метрики заключается в следующем: недетерминизм синтезированной модели возникает каждый раз, когда два или более сценариев описывают различное поведение для одного и того же принимаемого сообщения. На практике, это обычно является следствием зависимости поведения от истории выполнения, а трассы не содержат достаточно информации. Большие занчения метрики недетерминированности синтезированной SDL модели требуют проведения дополнительных итераций.
74 7.3.4 Исследование SDL модели Целью данного этапа является обновление исходного набора тестов за счет автоматической генерации новых тестов по синтезированной SDL спецификации, проверка критериев окончания итераций путем сравнения инструментального покрытия и тестового покрытия, а также метрики недетерминированности синтезированной модели. Шаг 10. Генерация TTCN тестов. Одной из основных целей восстановления SDL модели является использование ее автоматической генерации тестов. Техника генерации тестов по SDL моделям описаны в [19,20].
Рис. 27. Адаптация интерфейсов Шаг 11. Исполнение сгенерированных тестов на унаследованной системе и оценка покрытия. Исполнение сгенерированных тестов может потребовать дополнительной адаптации, т.е. преобразования абстрактных интерфейсов в исходные [19]. Адаптация интерфейсов представлена на рис. 27. Трассы и соответствующие им автоматически сгенерированные тесты используют так называемые абстрактные интерфейсы, соответствующие выбранной стратегии установки датчиков в исходный код унаследованного компонента. Абстрактный интерфейс использует некоторые внутренние функции («серый ящик») внутри системы, которые не обязательно доступны из окружения унаследованной системы. На Рис. 27 это показано как серая полость внутри прямоугольника, представляющего унаследованную систему. Вместе с тем, регрессионные тесты используют так называемые внешние интерфейсы системы («черный ящик»). На рис. 27 это представлено в виде нижнего черного прямоугольника на изображении унаследованной системы. Назначение адаптора (заштрихованный прямоугольник на рис. 27) состоит в том, чтобы
преобразовывать абстрактные интерфейсы во внешние. Наш опыт показывает, что должен достигаться некоторый компромисс между «глубиной» абстрактного интерфейса и простотой реализации адаптора. Абстрактный интерфейс на логическом уровне сущестенно упрощает трассы и позволяет получать более осмысленные синтезированные SDL модели. В некоторых случаях оказывается удобным реализовать специальную поддержку доступа к внутренним функциям для упрощения реализации адаптора. Шаг 12. Критерий завершения. Целью данного шага является проверка адекватности восстановленного поведения унаследованной системы в синтезированной модели. Как уже было отмечено ранее, методика восстановления предполагает проведение итераций. Неадекватное восстановление может быть вызвано следующими факторами: 1) некоторый важный сценарий не был исполнен при сборе трасс; 2) неправлильно был выбран абстрактный интерфейс при разработке стратегии установки датчиков (например, пропущен датчик, или датчик установлен неверно). По нашему опыту, неправильно установленные датчики выявляются при изучении инструментального покрытия. Пропущенные датчики на внешних интерфейсах приводят к большим значениям метрики недетерминированности синтезированной системы. Пропущенные датчики на выходных интерфейсах выявляются при изучении покрытия сгенерированных тестов. Такми образом, инструментальное покрытие, метрика недетерминированности и покрытие синтезированных тестов совместно являются удовлетворительным критерием адекватности синтезированной модели.
8. Выводы и направления дальнейших исследований Мы описали некоторый опыт в построении инструментальных систем нового поколения, основанных на использовании формальных методов и направленных на достижение практических улучшений процесса разработки программного обеспечения в телекоммуникационном секторе. Нами была описана методика ускоренной разработки программного обеспечения, охватывающая этапы составления спецификаций, проектирования,
75 тестирования и восстановления спецификаций телекоммуникационного программного обеспечения. Особенностями предлагаемой методики является применение формальных методов для описания моделей программного обеспечения на ранних этапах разработки, а также автоматизированное восстановления формальных спецификаций программного обеспечения на поздних этапах (этапе сопровождения). Методика основана на использовании стандартных формальных языков спецификации, широко распространенных в телекоммуникационном секторе: язык Спецификаций и Описаний (SDL), язык диаграмм взаимодействия (MSC), язык описания тестов (TTCN) и язык описания данных (ASN.1). В статье были описаны следующие ключевые шаги методики: • описание требований к проектируемой системе в виде сценариев, формализованных на языке диаграмм взаимодействия; • высокопроизводительная валидация требований с использованием исполняемых SDL моделей; • синтез исполнимых моделей требований на языке SDL по сценариям на языке MSC; • детализация моделей требование на языке SDL и доведение их до проектных моделей; • адаптивная генерация кода по спецификациям на языке SDL; • автоматическое восстановление SDL моделей по исходным текстам программ унаследованного программного обеспечения. Одной из главных задач нашего исследования является снижение барьеров для более широкого внедрения формальных методов на очень ранних и очень поздних этапах разработки. Методика ускоренной разработки программного обеспечения предполагает увеличение начальных этапов разработки. Утверждается, что увеличение продолжительности начальных этапов примерно на 17%, требуемых для составление и валидацию формальной модели требований и генерацию тестов на раннх этапах, может привести в общему сокращению сроков разработки на 20-30%. Мы разрабатываем инструментальные средства нового
поколения, поддерживающие нашу методику и позволяющие реализовать указанные сокращения сроков разработки. В настоящее время мы продолжаем выполнение исследований по программе, описанной в данной статье. Продолжается определение методики ускоренной разработки и уточнение отдельных ее шагов, а также определение открытой архитектуры, состоящей из языков и соответствующих инструментальных средств поддерживающх предлагаемую методику и автоматизирующих ее насколько возможно. Например, предметом нашего изучения являются методы быстрого построения тестов по SDL моделям и методы архитектурного анализа унаследованного телекоммуникационного программного обеспечения. Другие направления дальнейших исследований отдела инструментальных системе поддержки разработки включают в себя выполнение «пилотных проектов», имеющих целью оценить практическую применимость различных подходов к восстановлению формальных спецификаций, а также эффективность совместного использования методов прямой и обратной инженерии для ускорения сроков разработки и сокращения времени выхода продукта и его последующих версий на рынок. Литература 1. N. Mansurov, A. Kalinov, A. Ragozin, A. Chernov (1995), Design Issues of RASTA SDL-92 Translator, in Proc. of the 7-th SDL Forum, Oslo, Norway, 26-29 September, 1995, Elsevier Science Publishers B.V. (North-Holland), pp. 165-174 2. N. Mansurov, E. Laskavaya, A. Ragozin, A. Chernov, Об одном подходе к использованию языков SDL и MSC для обратной инженерии, в сб. Вопросы Кибернетики, Приложения Системного Программирования, N. 3, Москва, 3. N. Mansurov; A. Ragozin; A. Chernov; I. Mansurov: “Industrial strength code generation from SDL”, in A. Cavalli, A. Sarma (Eds.) SDL’97: TIME FOR TESTING – SDL, MSC and Trends, Proc. Of the 8-th SDL Forum, Evry, France, 23-26 September, 1997, , Elsevier Science Publishers B. V. (North-Holland), pp. 415—430. 4. N. Mansurov, A. Ragozin, A. Chernov, I.Mansurov, Tool suppport for algebraic Specifications of Data in SDL-92, in Proc. Formal Description Techniques IX, Kaiserslautern, Germany, 8-11 October 1996, Chapman & Hall, p 61-76. 5. N. Mansurov, R. Probert, Dynamic scenario-based approach to re-engineering of legacy telecommunication software, in Proc. 9th SDL
76
6.
7. 8.
9.
10.
11.
12.
13.
14. 15. 16.
17. 18. 19.
20.
Forum, Montreal, Canada, June 21-26, 1999, Elsevier Science Publishers B.V. (North-Holland). N. Mansurov, A. Ragozin, Generating readable programs from SDL, in Proc. SAM’98 workshop, 29 June-1 July, 1998, Humboldt University, Berlin, 1998. N. Rajala, D. Campara, N. Mansurov, inSight Reverse Engineering CASE Tool, in Proc. of the ICSE’99, Los Angeles, USA, 1998. N. Mansurov, D. Zhukov, Automatic synthesis of SDL models in Use Case Methodology, in Proc. 9th SDL Forum, Montreal, Canada, June 21-26, 1999, Elsevier Science Publishers B.V. (NorthHolland). N.Mansurov, A. Chernov, Генерация исполняемого кода по алгебраическим спецификациям, в сб. Вопросы Кибернетики, Приложения Системного Программирования, N. 2, Москва, 1996 [N.Mansurov, A. Ragozin, Генерация кода с простой и наглядной структурой по спецификациям на языке SDL, в сб. Вопросы Кибернетики, Приложения Системного Программирования, N. 3, Москва, 1997 N. Mansurov, A.Ragozin, Using declarative mappings for automatic code generation from SDL and ASN.1, in Proc. 9th SDL Forum, Montreal, Canada, June 21-26, 1999, Elsevier Science Publishers B.V. (North-Holland). N. Mansurov, O. Majlingova, Formal specification methodologies: MSC and SDL languages (lecture notes and tutorial), Moscow State University, Department of Computational Mathematics and Cybernetics, 1998 (in Russian). R. Probert, N. Mansurov, Improving time-tomarket using SDL tools and techniques (tutorial), Proc. 9th SDL Forum, Montreal, Canada, June 2126, 1999. [ITU-T (1993), CCITT Specification and Description Language (SDL), ITU-T, June 1994 Z.120 (1996) CCITT Message Sequence Charts (MSC), ITU-T, June 1992 R.L. Probert, O.Monkewich, TTCN: the international notation for specifying tests for communications systems, Computer Networks, Vol. 23, No. 5, 1992, pp. 417-738 ISO/IEC 8824: Specification of Abstract Syntax Notation One (ASN.1) (1989). Telelogic (1998), Telelogic ORCA and SDT 3.3, Telelogic AB, Box 4128, S-203 12 Malmoe, Sweden, 1998 Anders Ek, Jens Grabowski, Dieter Hogrefe, Richard Jerome, Beat Koch, Michael Schmitt, Towards the Industrial Use of Validation Techniques and Automatic Test Generation Methods for SDL Specifications, in Proc. of the 8-th SDL Forum, Evry, France, 23-26 September, 1997, Elsevier Science Publishers B.V. (NorthHolland), pp. 245-261 R. Probert, H. Ural, A. Williams, J. Li, R. Plackowski, Experience with rapid generation of functional tests using MSCs, SDL, and TTCN,
21.
22.
23.
24.
25. 26.
27.
28.
29.
submitted to Special Issue of Formal Descriptions Techniques in Practice of Computer Communications, 1999 G. Holzmann, Formal Methods for Early Fault Detection, (invited paper) in 4th Int. School and Symposium on Formal Techniques in Real Time and Fault Tolerant Systems, September 1996, Uppsala, Sweden. I. Jacobson, M. Christerson., P. Jonsson, G. Overgaard, Object-Oriented Software Engineering: A Use Case Driven Approach, Addison-Wesley, Reading, MA, 1992. G. Robert, F. Khendek, P. Grogono, Deriving an SDL specification with a given architecture from a set of MSCs, in Proc. of the 8-th SDL Forum, Evry, France, 23-26 September, 1997, Elsevier Science Publishers B.V. (North-Holland), pp. 197212 R.Tuok, L. Logrippo, Formal specification and use case generation for a mobile telephony system, Computer Networks and ISDN Systems, 30 (1998), pp. 1045-1063. M. Andersson, J. Bergstrand, Formalization of Use Cases with Message Sequence Charts, MSc Thesis, Lund Institute of Technology, May 1995 R. L. Probert, K. Saleh, Synthesis of communication protocols: survey and assessment, IEEE Transactions on Computers, 40(4), pp. 468475, April 1991 S. Leue, L. Mehrmann, M. Rezai, Synthesizing ROOM Models from Message Sequence Chart Specifications, University of Waterloo, Technical Report 98-06, 1998 S. Some, R. Dssouli, and J. Vaucher, From scenarios to timed automata: Building specifications from user requirements, In Proc. 2nd Asia Pacific Software Engineering Conference, IEEE, December 1995. R. Singh, J. Serviss, Code Generation using GEODE: A CASE Study, in Proc. of the 8-th SDL Forum, Evry, France, 23-26 September, 1997, Elsevier Science Publishers B.V. (North-Holland), pp. 539-550
30. J. Rumbaugh, I. Jacobson, G. Booch, The Unified Modelling Language Reference Manual, AddisonWesley, 1999 31. A. Ragozin, Automatic generation and execution of programs from SDL specifications, PhD thesis, Moscow State University, 1999
Об одной методологии автономного адаптивного управления1 А. А. Жданов, С. В. Арсеньев (Москва, ИСП РАН), В.А. Половников (Киров, ВятГТУ)
Аннотация В статье рассматриваются основные положения методологии построения управляющих систем на имитационных принципах, которая названа методом автономного адаптивного управления (ААУ). Из общих для всех нервных систем свойств: дискретности строения и принципа действия, высокой неопределенности начальных знаний и приспособленности аппаратно-программной компоненты к окружающей среде, а также необходимости осуществления управления и обучения в одном процессе выводятся принцип действия и строение управляющей системы. Предлагаются конкретные решения, позволяющие строить практически действующие управляющие системы, работающие с сравнительно простыми знаниями. Решения описывают способы построения формальных нейронов, подсистем формирования и распознавания образов, базы знаний, принятия решений и аппарата эмоций. Описаны примеры нескольких практических приложений. Проведено сравнение предлагаемого подхода с альтернативными направлениями систем искусственного интеллекта. Показано, что предлагаемый подход может составить новое направление, которое целесообразно назвать ″системы автономного искусственного интеллекта″.
1. Введение Задача моделирования живого мозга всегда вызывала повышенный интерес. Однако осознание чрезвычайной сложности объекта моделирования и выполняемых им функций ставила и продолжает ставить исследователей в тупик. Достаточно сказать, что мозг человека состоит из 1011 нервных клеток, соединенных 1014 связями, что средний размер нейрона менее 0.1 мм, а длина его отростка – аксона может превышать один метр при толщине в несколько микрометров, что один нейрон может быть соединен с сотнями и тысячами 1
других нейронов при отсутствии какойлибо очевидной регулярности, чтобы представить трудности, которые стоят на пути решения данной задачи. Функции, выполняемые мозгом, также поражают своей сложностью. Задачи, которые решаются нервной системой даже самых простых организмов, например, задача управления движением тела, могут быть воспроизведены в искусственных системах только с использованием таких сложных инструментов, как дифференциальное и интегральное исчисление, методов оптимизации и т.д., а решение их в реальном времени требует применения компьютеров. И уже за пределами понимания лежит тот факт, что этот же мозг одновременно легко решает и такие задачи, как формирование и распознавание образов, обучение и адаптация, генерирование целей и планов их достижения, принятие решений, в том числе на основе прогнозирования альтернативных вариантов и моделирования ситуаций в коллективе себе подобных посредством языка, а также другие задачи, которые в настоящее время получили лишь частичные и не связанные друг с другом решения. Можно констатировать следующее: 1) в полной мере принцип действия мозга в настоящее время остается непонятным и не воспроизводится технически, 2) имеющиеся в настоящее время методы решения задач, соответствующих некоторым функциям мозга, не имеют, по всей видимости, ничего общего с тем, как эти задачи решаются мозгом. Основания для вывода (1) состоят в следующем: а) сегодня еще нельзя построить устройство, состоящее из 1011 параллельно работающих искусственных нейронов, каждый из которых осуществляет довольно сложную обработку информации; б) в настоящее время не существует убедительной функциональной модели нейрона, а также способов построения нейросетей, решающих задачи,
Работа выполнена при поддержке РФФИ грант № 97-01-00137
78 свойственные мозгу; в) логическая организация мозга не понятна, даже на идейном уровне отсутствует представление о существе таких проявлений мозга, как сознание, эмоции; г) передаваемая посредством генного аппарата информация отражает опыт предыдущих поколений и обеспечивает начальную приспособленность аппаратной, программной и информационной компонент мозга и всего организма к условиям его обитания, без которой невозможно решение задач выживания, управления, адаптации, накопления знаний. Вызывает сомнение, что длительный эволюционный отбор на протяжении уникальной истории можно заменить единовременным актом оптимизации системы при ее синтезе. Развитая методика организации эволюционного отбора также отсутствует. Основания для вывода (2) состоят в следующем. Точные науки и составляющие их объекты являются абстрактными образами, возникшими в человеческом мозге в результате развития его способностей к прогнозированию и выработке умственных моделей. Эти модели только отражают некоторые свойства природы и являются не более, чем инструментом, помогающим человеку найти и использовать закономерности природы. В реальной природе не существовало таких объектов, как дифференциалы, интегралы и т.п. Тем самым, это есть новые объекты в природе, способные дать альтернативное решение некоторым задачам, ранее доступным только природе. Например, цапля обучается балансировать, стоя на одной ноге. Ее мозг решает задачу обучения и управления посредством нервных процессов, происходящих в сети нейронов, с участие органов чувств и мышечного аппарата. Создав математический аппарат, человек получил возможность смоделировать это явление на основе дифференциального исчисления и построить искусственное устройство, способное балансировать на одной опоре. Теперь в природе имеется уже два объекта, способных решать эту сложную задачу балансировки – мозг и искусственное устройство. Но принцип работы у них совершенно разный. В мозге цапли дифференциальные уравнения не решаются ни в процессе управления, ни на этапе обучения. Несмотря на успехи математического моделирования, возможности построения управляющих систем на этой основе ограничены. Если в
примере с цаплей одновременно потребуется воспроизвести и такие ее способности, как умение летать, решать навигационные задачи в длительных перелетах, общаться в стае, воспитывать потомство и т.д., то заведомо можно сказать, что точные науки тут не помогут из-за резкого усложнения математической модели. Однако в настоящее время в природе появился третий объект, способный балансировать на одной опоре. Это устройство, управляемое нейросетью. Нейросеть – это пока еще очень простая модель небольшого фрагмента мозга. Тем самым - это принципиально новое явление в природе - искусственная нервная система. От управляющей системы, построенной на основе классических математических наук, нейросеть отличается тем, что она без переделок может быть обучена и другим задачам, например, управлению полетом, распознаванию речи и т.п. Очевидно, что задача приближения свойств современных нейросетей к свойствам мозга требует дальнейшего осмысления принципов работы мозга, его структуры как цельной системы, функций отдельных его подсистем и элементов. Этим определяется предмет исследования настоящей работы. Практическая актуальность создания таких систем связана с возрастающим спросом на системы управления для объектов с плохо формализуемыми свойствами, требующими адаптации непосредственно в процессе управления. В этом направлении получено много теоретических и практических результатов. Успехи прагматического направления исследований по искусственному интеллекту отодвинули в последние два десятилетия на второй план исходную задачу изучения управления в живых организмах, о которой говорил Н. Винер [1]. Имитационное направление, которому уделяли внимание такие исследователи, как У. Кеннон [2], П. К. Анохин [3], А. А. Ляпунов [4], М. Мессарович [5] и многие другие, всегда являлось источником радикальных идей, которые прагматическое направление доводило в эволюционном порядке до практически полезных реализаций. Обратное возадействие прагматики на имитацию также является плодотворным, поскольку привносит новый математический и технический инструментарий, позволяющий строить и исследовать математические модели систем.
79 Отметим также, что, на наш взгляд, в настоящее время после пятидесятилетнего развития в прагматическом направлении формальных моделей нейрона и нейросети, предложенных У. Маккалоком и У. Питтсом в 1943 году [6] и Ф. Розенблаттом в 1953 году [7] (направление получило название ″искусственные нейронные сети (ИНН)″) наступает необходимость перехода к более адекватным действительности моделям нейрона, нервной системы и мозга. С одной стороны, накопился груз претензий к используемым в ИНН сильно упрощенным моделям нейрона и нейросети, претендующим, в лучшем случае, на простую модель небольшого регулярного участка нервной системы. С другой стороны, складывается впечатление, что в научном сообществе уже наработан и достаточно развит новый идейный, математический и программно-аппаратный инструментарий, который в совокупности может придать решению проблемы имитации новый импульс.
2. Имитационный метод автономного адаптивного управления Здесь коротко представим основные положения концептуальной модели нервных систем, названной методом “автономного адаптивного управления” (ААУ) [8-21]. Пусть под управляющей системой (УС) понимается моделируемая нервная система, погруженная в организм - объект управления (ОУ), под системой пусть понимается совокупность УС, ОУ и среды. Примем следующие четыре исходных условия, характерных для нервных систем. 1. ″Условие автономности″ под которым будем понимать только то обстоятельство, что УС является подсистемой ОУ, т.е. УС находится на борту ОУ и осуществляет управление на основе знаний, добываемых самостоятельно, взаимодействуя со своим окружением посредством блока датчиков (БД) и исполняющего органа (ИО). Тем самым УС ⊂ ОУ ⊂ Среда = Система, УС ∪ БД ∪ ИО = ОУ. 2. ″Условие дискретности″, которое отражает дискретность структуры УС (конечное множество нейронов, связей, датчиков, исполнителей) и способов ее функционирования (дискретность нервных импульсов, образов – как элементов информации, моментов времени). При этом возможен
непрерывный характер изменения некоторых параметров, таких как размеры синапсов, частотные характеристики импульсных последовательностей. 3. ″Условие максимальной начальной приспособленности″ отражает наличие приспособленности ОУ и УС к усредненным условиям жизни ОУ в данной среде в результате действия механизмов типа естественного отбора, что определяет типы датчиков и исполнителей, классы потенциально возможных в данной системе образов, оценки качества важнейших для ОУ образов, и т.п. При синтезе ОУ и УС процесс естественного отбора, возможно, может быть заменен максимальным использованием априорной информации. 4. ″Условие минимума исходных знаний″ отражает наличие информационных пространств, которые должны быть заполнены знаниями, найденными УС в процессе функционирования в реальной системе. Это условие соответствует наличию максимальной неопределенности свойств системы, в момент начала функционирования УС. Целевыми функциями УС должны быть а) выживание ОУ и б) накопление знаний. Эти две целевые функции взаимосвязаны в том отношении, что достижение одной из них повышает вероятность достижения другой.
Рис. 1. Представление о системе Из сказанного вынужденно следует представление о системе (рис.1), в котором можно видеть ОУ, погруженным в среду, УС погруженной в ОУ, а также все возможные маршруты распространения воздействий в системе (помеченные
80 буквами стрелки на рисунке) [8]. Пусть каждый из этих макрообъектов оказывает воздействия на систему через свой выход, каждый из макрообъектов пусть воспринимает воздействия системы через свой вход. Кроме того, в системе важно наличие источников случайных воздействий (белые кружки на рисунке ″истоки″) и мест поглощения воздействий (черные кружки на рисунке - ″стоки″). Очевидно, что для достижения своих целевых функций УС должна найти те из воздействий h, которые образуют цикл ″управляемого взаимодействия″ h → d → i → a → h → …, зафиксировать информационное отображение цикла управляющего воздействия (УВ) в своей памяти – базе знаний (БЗ), оценить полезность тех или иных элементов знаний и использовать эти знания для выживания, одновременно прилагая усилия для получения и накопления новых знаний. Здесь a – это информационный процесс в УС, h – процесс преобразования информационных команд в физические воздействия, d это различные процессы в окружающей среде, i – процесс преобразования части входных воздействий в информационные входные сигналы для УС. Наличие в системе истоков и стоков вносит в управляемое взаимодействие многочисленные случайные компоненты и приводит к потерям информации. Накапливая знания, УС стремится к уменьшению неопределенности в своем отображении управляемого взаимодействия [9]. Подобное макроописание позволяет понять задачу, которую должна решать УС. В общем виде можно видеть следующую ее постановку. На заданное множество входных полюсов УС v1, v2, …, vi, ,…, vn (например, это n бинарных выходов БД) поступает входной поток информации. Пусть, например, это будет эквидистантная во времени последовательность двоичных векторов Va(t1), Vb(t2),…, Vc(tk),…, Vd(t), где t – текущий момент времени. Если последовательность не эквидистантная, то должны быть средства синхронизации потоков данных. Согласно рис. 1, семантически каждый вектор Vc(tk) может содержать информацию, пришедшую ко входу УС по маршрутам i, b и/или p. Здесь i – это информация, поступившая с датчиков, b – информация, отражающая действия, совершенные УС, p – это незакономерные помехи от истоков в ОУ (информация от i и b также содержит случайные компоненты). Информация, поступающая по маршрутам i,
b и p, может отображаться на определенные подмножества компонент вектора Vc(tk).
Рис. 2. Примеры образов Первая задача, которую должна и может решать УС, состоит в нахождении неслучайных регулярных пространственновременных комбинаций компонент в потоке входных векторов Va(t1), Vb(t2),…, Vc(tk),…, Vd(t). Произвольные примеры трех таких образов показаны на рис. 2. Если УС обнаруживает наличие такой регулярности, то УС должна: а) запомнить информацию о ней как самостоятельный объект – образ [9,10], б) уметь распознавать прообраз этого образа во входной информации (регулярность, которая привела к формированию образа) при его последующих появлениях, в) при накоплении достаточной статистической надежности – уметь распознавать образ соответствующий протяженному во времени прообразу раньше, чем закончится его наблюдение на входных полюсах, а также распознавать при наличии помех, г) оценить соответствие этого образа целевой функции выживания ОУ. Путь к решению последней задачи мы видим в организации в УС специальной подсистемы, которая эквивалентна аппарату эмоций в живом организме. Это многофункциональная подсистема, основная задача которой – соотносить отвлеченные информационные сигналы, например, сигналы о распознавании образов, отображающих текущие состояния ОУ, с объективной полезностью или опасностью их прообразов для выживания ОУ. Безусловно, такая оценка для важнейших состояний ОУ (температура среды, количество поглощенной пищи и т.п.) может быть найдена опытным путем в эволюционной предыстории предков ОУ, а для искусственных ОУ – выведена из априорной информации. Оценки для образов, которые связаны с конкретными условиями существования данного ОУ, могут быть найдены УС опытным путем
81 посредством корреляционного анализа фактов распознавания этих образов и значений некоторой текущей интегральной оценки состояния ОУ, которую обозначим St. В свою очередь, текущее значение оценки St зависит от оценок всех распознанных в текущий момент образов. Формальное описание способов получения таких оценок (фактически – аппарата эмоций) дано в [11]. Здесь обратим внимание на две важных функции аппарата эмоций. Это закрепленное в УС стремление к получению все более высоких оценок St, что является причиной постоянной активности УС, направленной на достижение обеих указанных целевых функций. Кроме того, текущее значение оценки St определяет целесообразную глубину просмотра базы знаний при принятии решений в текущей ситуации (для быстрого принятии решения в угрожающей ситуации можно не анализировать второстепенные последствия выбираемого действия – образы с меньшими оценками). Пусть УС сформировала некоторый образ, запомнила его в памяти сформированных образов в виде объекта, который обозначим Ok, и в некоторый момент t распознает его, что обозначим как Otk =1 (если сформированный образ Ok не распознан в момент t, то полагаем Otk =0). Пусть, например, прообразом данного образа является некоторый пространственно-временной процесс длительностью T тактов, но УС распознала образ уже через T’ тактов после его начала tks, и T’< T. Если семантически прообраз данного образа в векторах Va(tks), Vb(tks+1),…, Vc(tks+T’),…, Vd(tks+T) представлял собой отображение информации, пришедшей на вход УС по маршруту i (см. рис.1), то это сравнительно простой случай, интересный в основном тем, что УС имеет прогноз, в частности, изменения оценки своего состояния St к моменту, когда завершится наблюдение всего прообраза. Одновременно может быть распознано некоторое множество образов. Однако ситуация становится более интересной, если в прообразе распознанного образа имел место хотя бы один вектор V(t), отражающий информацию, пришедшую к УС по маршруту b, т.е. в прообраз входило некоторое действие, совершенное УС (например, это сигнал от рецепторов о том, что была сокращена такая-то мышца в результате соответствующей команды). Обозначим такое действие символом Yl. Тогда прообраз можно разбить на три последовательных во времени
составляющих: i) информация о ситуации a, ii) информация о действии l, iii) информация о ситуации b. Поскольку, по определению, прообраз сформированного образа – явление не случайное, то данную тройку можно интерпретировать как импликацию ″условие → действие → следствие″. Очевидно, что в данной ситуации могло быть распознано два или более образов (рис. 3), имеющих одинаковое условие (ситуацию a), разные действия (действие m) и, возможно, разные следствия (ситуацию c).
Рис. 3. Несколько образов с одним условием Итак, если в некоторый момент а) УС одновременно распознает несколько временных образов, при этом б) распознавание наступило раньше окончания наблюдения прообразов, в) в составе прообразов ожидаются альтернативные действия, ведущие к альтернативным последствиям, г) распознанные образы имеют свои оценки, то появляется возможность принятия решения на основании сравнения ожидаемых приращений интегральной оценки качества состояния St для альтернативных действий [10,11]. Если будущий результат действия, предвидимый УС в текущий момент, влечет распознавание образов, которые могут быть распознаны по результатам планируемого действия, т.е. причинно-следственная цепочка образов и действий продолжается на несколько шагов в будущее, а УС при этом обладает языковыми средствами для манипулирования с этими образами и действиями из своей базы знаний, то появляются основания говорить об интеллекте [13]. Поскольку происходит формирование новых образов, то возможна ситуация, когда альтернативные действия, приносившие ранее одинаковый конечный результат распознавание одинаковых образов, начнут
82 различаться в отношении новых сформированных образов, т.е. – более тонких последствий выбираемого действия. Учет этих различий делает действия УС со временем все более точными, а их последствия – все более предсказуемыми [9,11]. Это одна из возможностей саморазвития УС. Рассмотренная интеллектуальная управляющая система обладает следующими основными свойствами. • Поведение УС мотивируется, определяется, направляется и оценивается аппаратом эмоций, целевая функция которого содержит в себе явно или неявно цели выживания и накопления знаний. • УС обладает внутренней активностью, направленной на расширение знаний, повышающих вероятность выживания. • УС обладает свойствами адаптивности и саморазвития. Формируются и оцениваются новые образы, формируются и уточняются новые действия, увеличивается глубина прогнозирования последствий альтернативных вариантов действий и тд. • Знания УС сильно зависят от ее индивидуального опыта, в том числе от случайных событий, т.е. УС обладает своей индивидуальностью.
применение персептронов и генетического подхода, либо использование аппарата эмоций в качестве учителя. Напомним, что задача распознавания образов даже таких простых регулярностей как периодические компоненты во временных рядах требует применения сложного математического аппарата анализа временных рядов. Мы полагаем, что поиск неслучайных составляющих во входном многоканальном потоке входных данных должен основываться на аппарате корреляционного анализа, тогда решение о формировании нового образа может приниматься при накоплении достаточных статистических оснований.
3. Проблемы создания систем ААУ и пути их реализации
В естественных системах аппарат ФРО строится на основе нейронов. Очевидно, что нейрон должен и может накапливать статистику по наблюдаемым входным векторам, изменять свой способ функционирования при появлении достаточных статистических оснований, говорящих о неслучайной природе прообраза, т.е. формировать образ, и быстро распознавать уже сформированный образ. Нами разработано несколько формальных нейронов с такими свойствами [12,14,15,17,18]. Описание основной модели нейрона (рис. 4) состоит в следующем. На вход нейрона nw в момент t поступает двоичный вектор X = (x1, x2, ... , xi, ... , xm) и
Как видно из сделанного качественного описания рассматриваемых систем, их реализация сопряжена с необходимостью решения задач, некоторые из которых здесь перечислим. 1. Задача формирования и распознавания образов (ФРО) в потоке входной многоканальной информации [10,11]. В общем случае на вход ОУ поступают непрерывные воздействия различной физической природы (зрительные, звуковые и т.д.). Аппарат ФРО должен в процессе самообучения сформировать множество дискретных образов, соответствующих классам пространственно-временных регулярностей и далее распознавать такие образы. Распознаваемые образы порождают формирование образов над образами, т.е. образов более высокого порядка. Переход от континуальных величин к дискретным должен происходить уже в БД. В нетривиальных случаях при отсутствии априорного алфавита классов такого рода задача является трудной. В некоторых условиях для построения БД и/или начальных трактов аппарата ФРО возможно
Рис. 4. Основная модель нейрона
t
сигнал
Sw.
В
момент
t+1
производит выходные сигналы
нейрон
t+1 Ow
t+1
и S wk t+1
=
t bw
&
согласно логическим выражениям O w
¬
t lw
t Sw
& ((
t bw
&
t lw
)VO
t w
)иS
t+1 wk
=
t gw
t & . Значение сигнала b w в точке "b" t определяется зависимостью b w = 1, если t t hw/m > = p(N ), и b w = 0 в других случаях.
Здесь h w есть число таких компонент x i t
вектора X , которые имеют значение 1 в
83
t
t
момент t; N есть число событий b w = 1 в предыстории этого нейрона от t=0 до t; p(N) есть сигмоидальная функция. Последняя определена для значений N = 0, 1, ... , и уменьшается от некоторого значения p(0) = p max , p max <= 100%, до значения p(∞) = p min , pM,
t +1
распознан (O w =0). Несформированный образ не может быть распознан.
p min < p max . Кроме того, p(M) = p min < p M < p max ,
где M есть
константа. Значения p max , p M , p min и M задаются для каждого нейрона априори. t
Переменная
lw
показывает
состояние
элемента l w в момент t и может принимать значения 0 или 1, согласно условию: ltw = 0, если N t < M, и ltw = 1 иначе. Элемент T подобен триггеру, который переключается сигналом (btw & ltw)=1 (см. точку "c" на рис. 4) в состояние, при котором выходной сигнал
t +1 Ow
становится t
равным 1, и сигналом S w = 1 переключается в состояние, при котором t +1
выходной сигнал O w принимает значение t
0. Переменная g w определяется условием: gtw = 0, если Z t < L, и gtw = 1 иначе, где t
Z есть число единичных сигналов, наблюдавшихся в точке "c" в течение предыстории. Константы L определены для каждого нейрона. t
t
Векторы X , для которых b w = 1, ”обучают” нейрон (число N увеличивается). Число M для нейрона подобрано так, чтобы N не превысило M за время жизни нейрона, t
если такие векторы X есть случайные явления. С другой стороны, число N достигнет величины M в случае, если этот вектор есть неслучайное явление в системе (с заданной вероятностью ложной тревоги). t
Если событие N = M случится с нейроном n w , то мы говорим, что нейрон n w обучен и образ O w сформирован начиная с этого момента t. Необратимый процесс роста N от 0 до M в нейроне n w есть процесс обучения нейрона n w
и, тем самым,
процесс формирования образа O w . Если образ сформирован, то он не может уже быть ″расформирован″ (переучивание УС происходит за счет доучивания; память о прежних образах и знаниях сохраняется в обученных нейронах). Сформированный образ может быть распознан в текущий t +1
момент (O w =1) или может быть не
Рис. 5. Модификация модели нейрона t +1
Сигнал O w =1 может быть отключен t
сигналом S w = 1 только после того, как информация этого сигнала будет использована УС (см. рис 5.). Итак, эта модель нейрона содержит три необратимо обучаемых элемента, именно R w , l w и g w , и один триггерный элемент Tw. Выходной сигнал нейрона генерируется на следующем такте после получения входного вектора. Поскольку в общем случае нейрон может быть соединен не со всеми нейронами предыдущего слоя (см. ниже рис. 6), то прообразом образа является пространственно-временная последовательность сигналов на входе нейросети. Входы данного нейрона могут не иметь весов, в этом случае нейрон различает только единичные векторы с учетом полноты их состава, задаваемой функцией p(N). Нейрон обучается под воздействием единичных (с учетом функции p(N)) входных векторов, другими словами, нейрон способен обнаружить коррелирующие единичные сигналы, если они подаются на входы нейрона. На рис.5 показана модификация данного нейрона, учитывающая синаптические и другие возможные задержки Δi на отдельных синапсах, а также актуальную длительность τi сигнала, которая может быть связана, например, с шириной и скоростью прохождения волны деполяризации в месте аксонного холмика, и другими причинами, определяющими характерную длительность импульса, воспринимаемого элементом Rw как единичный сигнал. Будем полагать, что характерная длительность возбуждения, соответствующая единичному выходному сигналу yi=1 триггерного элемента Ti,
84 поддерживается не дольше, чем в течение времени τi. Величины задержек Δi и τi задаются при синтезе УС. Обучаться будет тот нейрон, у которого величины задержек совпадают с характером входного сигнала. Следующая модификация нейрона связана с моделированием известного факта ускорения роста тех синапсов, по которым приходят коррелирующие входные сигналы [17]. Это позволяет нейрону реагировать не только на единичный вектор, но на любую неслучайную комбинацию единичных входных сигналов.
сигналов от распознанных образов и сигналов оценки St текущего состояния ОУ [11]. Поэтому эту задачу также можно решать с помощью сети из указанных нейронов.
Рис. 7. Схема УС В целом УС, построенную по методу ААУ, в упрощенном виде можно изобразить схемой, показанной на рис. 7.
Рис. 6. Фрагмент сети Итак, сеть, собранная из рассмотренных нейронов (небольшой фрагмент сети показан на рис. 6), способна решать задачу ФРО. При этом априорная информация определяет топологию сети, а неопределенность требует соответствующего избытка нейронов. В сети обучатся те нейроны, на которые отображаются пространственно-временные закономерности входного потока информации. 2. Построение базы знаний и аппарата принятия решений. Поскольку рассмотренный нейрон фактически обнаруживает коррелирующие сигналы, то на его основе можно построить БЗ, где отдельный нейрон фиксирует рассмотренную выше тройку ″образ условия – образ действия – образ следствия″ [9,11,12,14-17,20]. В элементарном случае БЗ может быть представлена трехмерной матрицей нейронов, измерения и размерности которой соответствуют образам указанной тройки множеств. Принятие решения осуществляется обученными нейронами, что становится возможным при уменьшении порога p(N). 3. Построение аппарата эмоций. Идея определения оценок качества образов также основана на корреляционном анализе
Заметим, что предложенная схема допускает весьма простые решения. Так, в указанной тройке множеств ″множество образов условия – множество образов действия – множество образов результатов″ каждое из распознаваемых множеств может быть представлено, например, всего одним образом [20]. Даже такое простое решение позволяет строить практически полезные приложения [16]. Круг приложений систем ААУ будет расширяться по мере нахождения способов сокращения необходимого избытка нейронов. Пути решения проблемы избытка мы видим в: а) разработке методики задания оптимальной топологии нейронных подсетей УС на основе использования априорной информации об объекте управления, б) использовании генетических алгоритмов для выращивания сетей УС, в) применении известных методов поиска для динамического построения и перестроения сетей УС, а также использовании элементов других технологий.
4. Примеры практических приложений на основе метода ААУ Рассмотрим теперь несколько примеров построения УС в соответствии с рассмотренным принципом. Следует понимать, что всякое конкретное приложение обязательно дает возможность
85 того или иного упрощения общего подхода, в соответствии с наличием априорной информации. 4.1. ″Пилот″ - адаптивная система стабилизации углового движения автоматического космического аппарата В связи с усложнением научных экспериментов, проводимых на борту автоматических космических аппаратов (АКА), в связи с использованием АКА в качестве ретрансляторов и т.п. причин, повышаются требования к точности управления угловым положением АКА. Применение метода ААУ для построения управляющей системы может сопровождаться большей точностью управления, по сравнению с традиционными подходами [16].
Рис. 8. управления
Схема
АКА
как
объекта
На рис. 8 показана схема АКА, как объекта управления. Коротко рассмотрим традиционный способ управления. В некотором приближении полагается, что АКА представляет собой твердое тело (корпус АКА) с закрепленными на нем упругими нелинейными осциллирующими элементами (антенны, солнечные батареи, навесное научное и т.п. оборудование). С корпусом АКА связана система координат xyzO с центром O в центре масс mc. Имеется некоторая заданная система координат XYZO с центром также в центре масс. Требуется, чтобы системы координат xyzO и XYZO были совмещены, в этом будем полагать целевую функцию управления. На АКА могут воздействовать возмущающие моменты различной физической природы: магнитное и гравитационное поле, утечки газа, солнечный ветер и другие. Возмущающие моменты вызывают рассогласования связанной и заданной систем координат.
Рассогласования регистрируются посредством датчиков, измеряющих через интервал времени Δt (в рассматриваемом примере Δt=0.1 сек) углы отклонения ϕ(t) и угловые скорости ϕ′(t) относительно системы координат xyzO. Обнаружив рассогласование по углу и/или по угловой скорости, система управления, реализованная на бортовой ЦВМ (БЦВМ), обращается к своей памяти, где в табличной форме записан ″закон управления″, указывающий, какой управляющий момент следует развить приводу, чтобы устранить данное рассогласование. Для воздействия на угловое положение АКА используется так называемая инерционная система управления, состоящая из трех лежащих на осях Ox, Oy и Oz маховиков и пошаговых электродвигателей в качестве привода. Раскручивая соответствующий маховик с некоторым ускорением, можно создать определенной величины управляющий момент My относительно одной из осей Ox, Oy или Oz. Для устранения больших рассогласований могут использоваться и другие более сильные, но менее точные приводы. ″Закон управления″ My(t+1) = K(ϕ(t)⋅kϕ + ϕ′(t)⋅kϕ′) рассчитывается аналитически исходя из так называемой ″динамической схемы″ - математической модели углового движения АКА, представляющей собой систему нелинейных дифференциальных уравнений второго порядка, описывающих угловое движение корпуса АКА - твердого тела и некоторых основных осцилляторов. Численные значения параметров, закладываемых в математическую модель АКА, рассчитываются по результатам наземных стендовых испытаний АКА и его узлов. Точность, достижимая при данном способе управления, обусловлена соответствием математической модели АКА свойствам реального объекта. Причины несоответствия модели и свойств реального АКА в полете вызваны следующими основными упрощениями: корпус АКА не есть твердое тело; учитываются не все осциллирующие элементы; параметры, измеренные в наземных стендовых испытаниях, не точно соответствуют их значениям в условиях реального полета в космосе, поскольку на стенде трудно воспроизвести невесомость, глубокий вакуум, резкие перепады температуры; возможны изменения свойств элементов конструкции АКА в течении полета. Указанные причины ограничивают возможную точность управления
86 некоторыми границами. В рассматриваемом примере традиционная система управления обеспечивает точность по углу +/- 0.1 угловой секунды и по угловой скорости +/0.01 угловой секунды в секунду времени.
Рис. 9. Пространство поиска Применение метода ААУ для управления данным объектом состоит в следующем. Будем использовать УС ААУ только в той области пространства признаков, в которой традиционный способ управления неэффективен - для углов и угловых скоростей в пределах точности традиционного управления. За пределами этого пространства будем использовать обычное управление. Из априорной информации известно, что наблюдаемость и управляемость данного ОУ обеспечиваются при наблюдении за такими параметрами, как угол ϕ(t) и угловая скорость ϕ′(t)= dϕ /dt и воздействиях на ОУ с помощью управляющих моментов, не превышающих некоторой заданной величины, ⏐My⏐≤ Mз. В рассматриваемом варианте приложения ограничимся только этим минимальным набором параметров, но заметим, что в управление по методу ААУ может вовлекаться и другая наблюдательная информация. Итак, ограничим пространство поиска в пространстве признаков - фазовой плоскости (ϕ(t),ϕ′(t)) областью заданных значений ⏐ϕ(t)⏐≤ ϕз и ⏐ϕ′(t)⏐≤ ϕ′з. (рис. 9). Будем полагать, что при выходе параметров за заданные границы значений управление передается внешней системе управления, устраняющей рассогласование в течение некоторого отрезка времени, по завершении которого параметры ϕ(t),ϕ′(t) принимают случайные значения, в пределах границ пространства. Такие отрезки времени, когда управление осуществляется не УС ААУ, мы будем исключать из рассмотрения.
Согласно методу ААУ, в БЗ управляющей системы фиксируются закономерные связи между сформированными образами и выходными воздействиями УС. Поскольку здесь мы ограничиваемся наблюдениями только за ϕ(t) и ϕ′(t), а управлять будем посредством My, то можем сразу отделить в подсистемах ФРО и БЗ те множества образов, действий и их связей, для которых только и могут быть найдены закономерности. Очевидно, что эти простейшие закономерности будут состоять в том, что из некоторого состояния (ϕ(t),ϕ′(t)) под воздействием управляющего момента My(t) ОУ может перейти к моменту времени t+1 в состояние, описываемое некоторым множеством значений {ϕ(t+1),ϕ′(t+1)}. Поэтому в блоке ФРО следует задать условия для формирования образов, семантически соответствующих возможным состояниям (ϕ(t),ϕ′(t)) и {ϕ(t+1),ϕ′(t+1)}. При определении семантики образов удобно использовать некоторые элементы подхода к формализации семантики информации, описанные в работе [22]. Так, в образах можно видеть соответствие понятию ″сведение″. Согласно [22], на множестве сведений может быть установлено отношение общности, и выделяются более общие сведения и менее общие сведения. В этом смысле образы, соответствующие состоянию {ϕ(t+1),ϕ′(t+1)} являются более общими сведениями, чем образы, соответствующие состоянию (ϕ(t),ϕ′(t)). Поскольку УС, как дискретное устройство, обладает конечными множествами элементов памяти, входных и выходных полюсов, то число образов должно быть ограниченным. Введем дискретизацию наблюдаемых значений ϕ(t) и ϕ′(t) по уровню. Разобьем диапазон наблюдаемых значений ϕ(t) на интервалы следующим способом (рис. 9). Диапазон (ϕз ≤ ϕ(t) ≤ ϕз) разобьем, например, на N1 равных интервалов, которые пронумеруем номерами p=2,3,..., N1-1. Открытому диапазону ϕ(t) < - ϕз присвоим номер p = > ϕз 1. Открытому диапазону ϕ(t) присвоим номер p = N1. Аналогичным способом разобьем на интервалы диапазон возможных значений ϕ′(t) и пронумеруем интервалы номерами r = 1,2,...,N2. Тем самым поисковое пространство (ϕ(t),ϕ′(t)) разбивается на N = N1 ⋅ N2 непересекающуюся подобласть. Каждую такую подобласть будем полагать образом Oi , номер i=1,2,...,N которого есть номер
87 подобласти и определяется выражением i = N2 × (p - 1) + r. Процедуру формирования этих образов Oi, i=1,2,...,N, упраздняем, поскольку эти образы известны априори и здесь нет необходимости в наборе статистики. Процедура распознавания этих образов тоже крайне проста - блок ФРО должен определить координаты r и p и номер i подобласти, покрывающей текущие значения (ϕ(t),ϕ′(t)). Например, пусть на рисунке 9 в момент t распознан образ O47 (на фазовой плоскости ему соответствует подобласть, помеченная буквой А). Образы, соответствующие таким более общим сведениям о состоянии ОУ, как множества {ϕ(t),ϕ′(t)}, могут быть определены разными способами. Для нас здесь удобны сведения, описывающие состояния ОУ в связи с целевой функцией. Определим образы множеств {ϕ(t),ϕ′(t)} как подмножества различимых УС состояний, имеющих равные оценки качества. Пусть на фазовой плоскости (рис. 9) концентрические рамки с номерами E = 1,2,...,Emax будут соответствовать равным оценкам качества состояния ОУ. Центральная рамка с наибольшим номером Emax совпадает по своему положению в пространстве признаков с целевой функцией управления. Присвоим таким образам очередные порядковые номера Oi, i=N+1, N+2, ..., N+Emax (в порядке, соответствующем E = 1,2,..., Emax ). При развитии УС можно формировать и другие образы с очередными номерами, семантика которых определяется априорной информацией, либо имеет случайный характер, если априорная информация отсутствует. Блок оценивания качества состояний ОУ, идея которого подробно описана в [11], в данном приложении может отрабатывать очень простую функцию, поскольку здесь мы используем только заранее сформированные образы с заранее известными оценками качества. Пусть оценка качества состояния ОУ, как и оценка качества всякого образа, определяется номером E той рамки на фазовой плоскости, которая покрывает образ, описывающий данное состояние ОУ. Так, на рис. 9 образы O47 и O124 имеют одинаковую оценку E=3. В блоке формирования БЗ, согласно методу ААУ, определяются и фиксируются закономерные связи между воздействиями, образами и оценками качества. В момент t совокупность распознанных и нераспознанных образов по условию C({Oi(t)}) = 1 отделяет раздел БЗ,
содержащий истинные в данных условиях знания, и время Δτ принятия решения. Далее УС в отделенном разделе БЗ находит действие Yk, которое, согласно имеющимся знаниям, приведет к наибольшему улучшению состояния ОУ. В рассматриваемом приложении наиболее простые закономерности, которые могут быть найдены при использовании определенных выше образов, состоят в следующем. Условие C({Oi(t)})=1 есть (Oi(t)=1, i∈ (1,2,...,N); раздел БЗ, соответствующий этому условию, содержит знания в виде Yk(t) → (Oj(t+1)=1, j∈ (N+1, N+2,..., N+Emax)), где действие Yk (t) состоит из некоторого множества {n} номеров выходных воздействий. Выходное воздействие с номером n дает приводу команду развить определенный управляющий момент. Поскольку из состояния, соответствующего образу (Oj(t+1)=1, j∈ (N+1, N+2,..., N+Emax )), нельзя будет обнаружить дальнейших закономерных переходов, то дальнейших закономерностей искать не будем. Время Δτ принятия решения в данном приложении должно соответствовать циклу БЦВМ и быть постоянной величиной (в общем виде Δτ находится в функциональной зависимости от оценки состояния ОУ).
Рис. 10. Информационная структура для представления знаний В процессе обучения УС должна находить статистически достоверные знания рассмотренного вида, что возможно при анализе предыстории, т.е. при рассмотрении последовательностей вида ((Oi(t-1)=1)⏐ Yk(t-1)) → (Oj(t)=1) → Ej(t) , где i∈ (1,2,...,N), j∈ (N+1, N+2,..., N+Emax)), k∈ (1,2,...,Nm). По мере обнаружения неслучайных последовательностей УС должна представлять их в БЗ. В рассмотренном простом случае подходящей информационной структурой для представления знаний может быть простая таблица (рис. 10). Столбцам таблицы БЗ соответствуют номера i∈ (1,2,...,N) образов Oi(t-1), строкам таблицы соответствуют номера k∈ (1,2,...,Nm) действий Yk(t-1). В клетку (i,k) таблицы БЗ записывается номер j∈ (N+1, N+2,..., N+Emax) образа (Oj(t)=1), а
88 также его оценка качества Ej. В рассматриваемом случае достаточно записывать только оценку Ej. В процессе принятия решений УС интерпретирует записи БЗ как последовательности вида ((Oi(t)=1)⏐Yk(t)) → (Oj(t+1)=1)→ Ej(t+1) . Распознав образ Oi(t) с номером i, УС выбирает действие с таким номером k, которому соответствует большая ожидаемая оценка Ej(t+1). При этом УС удовлетворяет требованиям целевой функции, предусматривающей стремление к улучшению состояния ОУ. Если в БЗ имеется несколько альтернативных вариантов (здесь несколько одинаковых максимальных оценок Ej или отсутствие записей), то УС выбирает один из них случайным способом, чем обеспечивается удовлетворение второй целевой функции, предусматривающей стремление к получению новых знаний. Тем самым, процедура принятия решений содержит и детерминированную и случайную компоненты, как этого требует метод ААУ.
Рис. 11. Управление при трех стадиях наполнения БЗ По мере накопления знаний в БЗ, качество управления возрастает. Рис. 11 демонстрирует управление при трех стадиях наполнения БЗ. Количественно степень наполнения БЗ можно характеризовать отношением числа заполненных клеток БЗ к общему объему БЗ.
4.2. Прототип адаптивной системы поддержки принятия решений при управлении социальными объектами В органах социального управления каждое лицо, принимающее решения (ЛПР), или соответствующий орган, по своей сути является системой ААУ. В этом случае, как и в других рассматриваемых случаях, система состоит из УС, исполняющего органа (ИО), среды и блока датчиков (БД). Здесь УС - это ЛПР, БД - это люди и технические средства, подготавливающие данные к виду, который воспринимается ЛПР; ИО - это средства, обеспечивающие реализацию команд, поступающих от ЛПР, например, органы исполнительной власти; среда - это та социальная структура, которой управляет ЛПР. Четких границ между функциями, которые можно относить к ИО, БД и среде, определить невозможно, а в соответствии с методологией ААУ, в этом и нет необходимости. Будем полагать, что УС управляет всей системой, которая объединяет в себе ИО, БД и среду, входы которой есть входы ИО, а выходами являются выходы БД. Будем рассматривать сравнительно простой случай [16], ориентируясь на следующие нестрогие условия: • свойства среды плохо известны, но стационарны в некотором смысле; • акты управления эквидистантны во времени; • ЛПР способно контролировать не слишком большое число параметров; • набор возможных решений ЛПР конечен и может быть перенумерован. Блок датчиков пусть представляет собой систему подготовки данных для ЛПР в виде, например, временного ряда числовых данных x(t) и k(t) (рис. 12). Пусть каждое число x(t) есть агрегированная интегральная рейтинговая оценка, полученная с помощью экспертов и характеризующая состояние тех параметров ОУ, которые интересуют ЛПР. На множестве значений x(t) ЛПР может определить целевую функцию своего управления. Например, пусть ЛПР стремится к уменьшению значений x(t) на рисунке 12. Временной ряд k(t) пусть представляет номера решений (воздействий), посредством которых управляет ЛПР.
89
Рис. 12. Включение в систему УС ААУ в систему параллельно с ЛПР Включим УС ААУ в систему параллельно с ЛПР (рис. 12). В процессе работы системы УС ведет наблюдение за данными, поступающими с БД, и за решениями, принятыми ЛПР. В УС на этапе обучения следует отключить аппарат принятия решений, и подавать в УС информацию о решениях, принятых ЛПР. В остальном обучение осуществляется так, будто решения принимаются самой УС. О степени обученности УС можно судить по наполнению БЗ, либо по специальным тестам. Когда объем знаний в БЗ достигнет необходимого уровня, можно разрешать УС принимать управляющие решения. В этом режиме УС наблюдает информацию x(t), предоставляемую БД, сопоставляет ее с эмпирическими знаниями своей БЗ и принимает решение z(t+1). Однако решение, принятое УС, не передается непосредственно ИО, а поступает к ЛПР, которое принимает окончательное решение y(t+1). Информация о решении y(t+1) поступает к УС для дальнейшего ее обучения. ЛПР может направить УС запрос q на выдачу объяснений принятому решению. При разработке прототипа системы, названного системой ″Тактик″, необходимо было располагать математической моделью объекта управления (объединяющей в себе модели ИО, среды и БД) для отладки системы, быстрого ее обучения, тестирования и исследования свойств. Требования к соответствию такой модели свойствам реального ОУ могут быть самыми простыми - наличие нелинейных функциональных зависимостей выходной информации от входных воздействий при возможной помехе. Это соответствует условию высокой неопределенности исходных знаний о свойствах ОУ и расчетам на оговоренную выше универсальность УС. Пример обучения и управления одной из таких моделей ОУ показан на рис. 13-15. УС наблюдала за имитацией ″интегральной рейтинговой оценки″ (вторая сверху кривая) и управляла
процессом при помощи управляющих воздействий (третья сверху кривая). Целью управления было - прижать рейтинговую оценку к нулевому уровню значений. Можно видеть, что по мере накопления знаний в БЗ качество управления повышается от рис. 13 к рис. 15. Здесь система ″Тактик″ работала в полностью автоматическом режиме.
Рис. 13. Пример обучения и управления одной модели ОУ (1)
Рис. 14. Пример обучения и управления одной модели ОУ (2) Очевидно, что одна из проблем использования метода ААУ в этом приложении состоит в большом времени, необходимом для накопления знаний, достаточных для качественного управления, поскольку характерное время цикла управления имеет порядок суток или даже недель. В таких условиях необходимо использовать предварительное обучение БЗ. Предусматривались две возможности предварительного обучения. Первая из них
90 состоит в обучении по адекватной математической модели данной социальной системы, как ОУ. При этом задача построения такой модели выделяется в отдельную проблему, которую здесь мы рассматривать не будем. Вторая возможность предварительного обучения состоит в использовании архивной информации, описывающей реальный процесс управления данным ОУ, если таковая имеется.
Рис. 15. Пример обучения и управления одной модели ОУ (3)
Рис. 16. Предварительные результаты работы системы ″Тактик″ Проверка возможностей обучения УС ААУ по архивным выборкам данных показала применимость такого подхода. На рис. 16 представлены предварительные результаты работы системы ″Тактик″ на обучающей выборке реальных данных. Верхний график есть управляемый процесс, качество состояния оценивается тем выше, чем меньше значения величин. Нижний график отражает управляющие воздействия. Система ″Тактик″ несколько раз просматривала эти данные объемом 90
точек, после чего эта же выборка предъявлялась в качестве реальной ситуации. Анализируя процесс, УС выдавала рекомендации по управляющим воздействиям, показанные квадратиками. Однако очевидно, что УС не могла влиять на архивный процесс, а о качестве управления можно судить, сравнивая решения, принятые УС, с зафиксированными в архиве решениями, реально принятыми ЛПР. Можно видеть, что в данном примере в 37% случаев решения, принятые системой ″Тактик″, совпадают с реальными решениями ЛПР, в 15% случаев решения близки, а в 19% случаев система ″Тактик″ приняла решения, представляющиеся более правильными. Например, в начале выборки, когда управляемый процесс ухудшался, УС рекомендовала более активные действия, чем те, которые принимало ЛПР, и которые не смогли быстро остановить ухудшение процесса. Или в нескольких случаях, когда управляемый процесс улучшался, УС принимала решения не совершать управляющих воздействий, что могло бы привести к экономии средств на реализацию управляющих воздействий по сравнению с реальными затратами, имевшими место. Таким образом, предварительное обучение УС представляется возможным несколькими способами и целесообразным. При этом предварительные знания могут пополняться и уточняться при последующем управлении в реальном времени. Необходимо также пояснить отличия метода ААУ от известных нейросетевых подходов. Как было сказано выше, современные нейросетевые системы предназначены в основном для решения задачи обучения распознаванию. В этом качестве они могут использоваться для управления, если заранее известно, какие действия следует предпринимать при распознавании того или иного образа (в случае ААУ такая информация может отсутствовать), либо если требуется решить задачу прогнозирования (система ААУ решает задачу прогнозирования как одну из своих подзадач, идя дальше, и предлагая управляющие решения). На рис. 17 на примере той же выборки данных показано, как применяется обычная нейросетевая программа. После многократного просмотра выборки, нейросетевая программа просматривает выборку в режиме предсказания, и в случае, когда она распознает ситуацию, выдает свой прогноз
91 управляемого процесса (показано квадратиками на рис. 17). Таким образом, обычная нейросеть прогнозирует, каким будет значение управляемого процесса в текущих условиях и при совершенном управляющем воздействии. Напротив, УС в методе ААУ в этой же ситуации идет дальше и сразу указывает лучший вариант управляющего воздействия (рис. 16).
Рис. 17. Применение обычной нейросетевой программы Как можно видеть, в этом приложении УС ААУ работает не в обычном для нее автоматическом режиме, а в режиме полуавтоматическом, выполняя роль экспертной системы. При этом, в отличие от экспертной системы, УС ААУ работает на своего рода ″рефлекторном уровне″, набирая статистику по прецедентам пространственно-временных вариаций наблюдаемой информации и их связям с выходными воздействиями, не вдаваясь в содержательный смысл найденных закономерностей. 4.3. Использование метода ААУ для управления финансовыми операциями Рассмотренный выше прототип системы поддержки принятия решений ″Тактик″ может быть использован и для поддержки принятия решений в экономической сфере. Пусть ОУ есть некоторая рыночная система. ЛПР отслеживает интересующий его параметр и пытается обнаружить закономерности его временного хода. В зависимости от результатов своего прогнозирования развития ситуации ЛПР принимает очередное решение, например, о купле или продаже ценных бумаг. От предыдущего случая данная система может отличаться тем, что воздействия ЛПР не в состоянии повлиять на ОУ в силу относительной слабости такого воздействия. В этом случае воздействие ЛПР влияет только на его собственную
прибыль и зависит от того, угадало ЛПР тенденцию поведения ОУ или не угадало. Тем не менее, метод ААУ может использоваться и в таком приложении, при этом основная нагрузка ложится на подсистему ФРО и ее способности отыскивать закономерности, в том числе в процессе их агрегирования, а также на свойства ААУ адаптироваться к изменениям свойств ОУ, что характерно для таких объектов, как финансовые системы. 4.4. Адаптивное управление активной подвеской Если подвеска технического устройства (например, транспортного средства) обладает активными элементами, позволяющими воздействовать на вертикальное перемещение h корпуса устройства, то появляется возможность стабилизации положения корпуса. Однако точно формализовать реакцию данного технического устройства на управляющее воздействие активных элементов подвески заранее крайне трудно, поскольку эта реакция будет зависеть от многих индивидуальных особенностей. Например, для транспортного средства это: состояние амортизаторов, характер груза и его распределение в корпусе, характер дорожного покрытия, погодные условия и т.п. УС ”Пилот” может обеспечить адаптацию к текущим условиям, характеру и распределению нагрузки, состоянию амортизаторов. В результате адаптации реакция Mc активной подвески на возмущения Md будет оптимальной и качество стабилизации увеличится (сплошная кривая h на рис. 18).
Рис. 18. стабилизации
Увеличение
качества
4.5. Обрабатывающие станки 4.5.1 Прокат фольги Вращающиеся валки прокатного стана имеют собственные частоты поперечных колебаний, возникающих при изменении
92 прилагаемых к валкам усилий (рис. 19а). Включение УС ААУ в контур управления валками позволит УС адаптироваться к колебательным характеристикам валков и управлять с учетом выявленных свойств, что позволит нейтрализовать колебания валков и улучшить качество проката (рис. 19б).
Рис. 19. Включение УС ААУ в контур управления валками 4.5.2 Токарная обработка При подводе резца к обрабатываемой на токарном станке детали возникают биения детали с собственной частотой, характерной для данной детали. В результате этого эффекта снижается качество обработки поверхности детали (рис. 20а). Включение УС ААУ в контур управления резцом позволит УС адаптироваться к колебательным свойствам обрабатываемой детали и управлять усилиями на резец так, чтобы уменьшить биения детали и улучшить качество обработки (рис. 20б).
Рис. 20. Улучшение качества токарной обработки 4.5.3 Стабилизация тока и напряжения источников энергии Каждая конкретная совокупность потребителей электроэнергии имеет свои динамические характеристики, определяющие их реакции на перепады тока и напряжения в сети. УС ААУ, введенная в состав системы управления источником энергии (блоки питания радиоаппаратуры, энергетические установки, электростанции и т.п.), может адаптироваться к свойствам потребителей и стабилизировать параметры электроэнергии в соответствии с найденными свойствами.
Результатом использования УС ААУ будет являться большая стабильность параметров электроэнергии. 4.5.4 Стабилизация параметров энергосистем Предприятия, потребляющие тепловую и электроэнергию, и управляющие ее распределением по своим потребителям, заинтересованы в снижении убытков, возникающих в связи с неоптимальным распределением энергии. На основе УС ААУ может быть построена система управления, которая уменьшит эти убытки за счет адаптации к свойствам потребителей.
5. Сравнительный анализ метода автономного адаптивного управления и альтернативных подходов Приведенное выше краткое описание метода ААУ позволяет определить круг альтернативных подходов, с которыми следует сравнить предлагаемый метод. Однако прежде выскажем несколько общих положений. • Всякий подход имеет свою историю, он был задуман с некоторой определенной целью, нашел удачное практическое применение в некотором определенном направлении, имел какие-то более или менее продвинутые и удачные варианты и модификации, приспосабливающие его для решения других задач. Очень часто исходные идеи, содержание теоретической проработки, круг наиболее широко используемых реализаций и инновационные модификации существенно различны. Поэтому при сравнении методов надо иметь в виду все эти аспекты. • Все подходы, которые будут упомянуты ниже, некогда имели свое начало в задаче имитации живого мозга. Затем эти подходы сильно разошлись под влиянием их успехов в соответствующих им практических приложениях, более того, каждое из них породило свой спектр вариантов направлений. Сегодня это расхождение достигло таких степеней, что часто абсолютно утрачено общее понимание постановок задач, методов решения, языков формального описания, критериев оценки получаемых результатов и понимание перспектив. Однако нам представляется, что в множестве спектров направлений, на которые распался каждый из подходов, возможно пересечение, связанное с
93 возвращением к исходной задаче имитации живого мозга. Те исследователи из разных направлений, которые озадачатся целью понять и смоделировать принцип действия мозга, в отдаленной перспективе придут хотя и своими путями, но к схожим решениям, поскольку имеют в виду один и тот же объект моделирования – мозг. В настоящее же время такие тенденции можно только с большим трудом угадывать. • Развивая свой подход ААУ, мы не стремились изобрести новый способ управления, но шли от попыток понять способ управления, существующий в природе. Главным критерием в теоретическом осмыслении для нас являлось соответствие биологическим оригиналам, тем их свойствам, которые понимались нами, как наиболее важные. Естественно, что в практических приложениях приходится часто опираться на прагматические решения, при этом при необходимости мы упрощали идеи метода ААУ, но не меняли их на другие искусственные подходы, не соответствующие методу. 5.1. Метод ААУ и нейросети Одним из возможных способов реализации управляющей системы, построенной в соответствии с методологией ААУ, является нейросетевая реализация на основе специально разработанных для данной системы нейроноподобных элементов и сетей. Тем самым появляются основания для анализа системы ААУ с позиций теории искусственных нейросетей (ИНС). В своем традиционном виде ИНС были задуманы для решения задачи обучения распознаванию с учителем. С этой целью они и используются в настоящее время наиболее широко. Назначение же системы ААУ – автономное (без учителя) адаптивное управление. Задача обучения распознаванию является только одной из подзадач управляющей системы ААУ. В последнее время в теории ИНС говорят о необходимости перехода ИНС к ″управляющей парадигме″, что, собственно, и реализовано в методе ААУ, если ее построить на нейросетях. ИНС можно использовать тогда, когда имеется обучающая выборка, состоящая из двух множеств, одно из которых содержит векторы входных данных, а другое – соответствующие векторы выходных данных. Если ИНС использовать как управляющую систему, то входные векторы
можно интерпретировать как образы ситуаций, а выходные векторы можно интерпретировать как коды действий, которые необходимо совершать при распознавании соответствующих ситуаций. Соответствие входов (образов ситуаций) и выходов (действий) для обучающей выборки должно быть известно заранее. Кроме того, над собственно нейросетью должно иметь место внешнее устройство, настраивающее веса соединений нейронов. Систему ААУ можно использовать для управления в случаях, когда а) закономерности во входной информации (образы ситуаций) заранее неизвестны и их следует найти, б) даже если образы будут обнаружены, то неизвестно, какие действия следует совершать при их распознавании, в) в управляющей системе имеется аппарат оценивания качества состояний объекта управления и целевые функции. Например, если для некоторого робота заранее известно, какие действия следует совершать при наблюдении определенных классов ситуаций, то ИНС можно обучить давать команду на выполнение этих действий при распознавании класса ситуации. Систему ААУ целесообразно применять, когда заранее неизвестны ни классы ситуаций, ни оптимальные способы поведения при их наблюдении. Система ААУ могла бы делать бы следующее: самостоятельно формировать классы (образы) наблюдаемых ситуаций, оценивать степень качества (опасности, полезности) этих образов, находить адекватные способы воздействия на прообразы этих образов, находить оптимальные способы реагирования на распознаваемые ситуации и все это осуществлять в режиме реального управления. Поскольку качество управления в системе ААУ повышается по мере накопления ею знаний, то возможно достижение состояний, когда будет получено более высокое качество управления, чем то, которое было зафиксировано в обучающей выборке для ИНС. ИНС представляют собой, как правило, регулярные однородные сети с полносвязными соединениями нейронов соседних слоев. Управляющая система ААУ состоит из нескольких подсетей с разным функциональным назначением и различным характером связей. При этом отдельный нейрон может быть связан с нейронами из разных слоев. В методе ААУ отдельный нейрон связан с отдельным образом, в ИНС – нет.
94 Формальные нейроны в методе ААУ существенно отличаются от формальных нейронов в ИНС. Нейрон в методе ААУ более сложен функционально. Он автоматически накапливает статистику в нескольких своих узлах и меняет свое функционирование при обнаружении определенных закономерностей. В нейронах ИНС этого нет. Нейрон ААУ имеет и учитывает временные задержки, что принципиально важно для обнаружения причинно-следственных связей в системе. Нейроны и сети ИНС непосредственных временных задержек не имеют. Роль ″учителя″ в методе ААУ играет аппарат эмоций – важная многофункциональная подсистема, обеспечивающая внутреннюю активность, целеполагание, оценку качества состояний системы и объектов знаний, которая работает параллельно с основным контуром обработки внешней входной информации. В теории ИНС только появляются предложения о введении в сеть дополнительной подсети, обеспечивающей целеполагание. Видимо, наиболее близким аналогом системы ААУ в области ИНС являются сети Хопфилда [23], имеющие обратные связи. Однако даже обученная сеть Хопфилда способна только реагировать на предъявленную ситуацию, в то время как система ААУ имеет внутреннюю активность, заставляющую ее даже в благоприятных условиях совершать некоторые действия, направленные на поиск новых знаний. Это принципиально иной способ поведения. Преимущество ИНС перед распознающей нейросетью системы ААУ состоит в удобстве перехода от континуальных величин к дискретным. Поэтому ИНС можно использовать, например, в роли блока датчиков для системы ААУ, а, возможно, и в других подсистемах. Сближение подходов ИНС и ААУ будет происходить по мере внесения в ИНС как минимум следующих положений: 1) переход к ″управляющей парадигме″; 2) дополнения ИНС, как распознающего блока, другими блоками, выполняющими получение и представление знаний, моделирование эмоций, принятие решений, т.е. блоками, в совокупности образующими автономную адаптивную управляющую систему; 3) переход от обучения с учителем к самообучению; 4) уход от однородности и полносвязности сети; 5) внесение временного параметра в работу нейросетей;
6) переход к формальным нейронам, более адекватным биологическим нервным клеткам в отношении их способности к автоматической самонастройке. Со стороны системы ААУ сближение возможно при развитии в методе ААУ подходов к работе с континуальными параметрами, описывающими границы классов. Это может быть введение непрерывных весов в состав формальных нейронов ААУ, либо использование традиционных ИНС для реализации различных подсистем системы ААУ. 5.2. Метод ААУ и экспертные системы При описании структуры управляющей системы ААУ, в ней при желании можно выделить отдельно систему, которую можно назвать базой знаний (БЗ). К БЗ можно отнести совокупность нейронов, сформировавших такие образы, в прообразы которых входила информация о действиях, совершенных самой управляющей системой (см. разд. 2), т.е. прообразы, которые можно интерпретировать как импликацию ″условие → действие → следствие″. Не все множество нейронов в управляющей системе обладает такими свойствами (отметим, что в мозге локализовать такую отдельную подсистему не удается, она является распределенной). Если при анализе системы ААУ все-таки выделить БЗ как отдельную подсистему, то можно говорить, что система ААУ есть система автоматического получения, накопления и использования знаний в реальном времени управления. Тем самым появляются основания для сравнения системы ААУ с экспертными системами (ЭС) [24]. Различия удобно объяснить при сравнении данных направлений и систем по их целям, назначению, содержанию используемых в системе знаний, степени автоматизации и способам реализации. Целью, стоящей перед разработчиками ЭС, является, по определению, создание прикладных интеллектуальных систем, предназначенных для оказания консультационной помощи специалистам, работающим в некоторых предметных областях. Целью методологии ААУ является построение концептуальной модели нервной системы и мозга, что относится к разряду фундаментальных проблем. С точки зрения назначения систем, ЭС предназначена для представления в ЭВМ знаний, накопленных человеком-экспертом, для дальнейшего их тиражирования и
95 использования в режиме поддержки принятия решений другими специалистами в данной предметной области. Если знания, накопленные в мозге человека, ранжировать по их сложности, комплексности, абстрактности, то ЭС, по их первоначальному определению, предназначены для работы с вербализованными посредством человеческого языка знаниями из области высокоинтеллектуальной профессиональной деятельности человека-специалиста. В свою очередь, система ААУ оперирует с диапазоном знаний, начинающимся от элементарной информации, поступающей в двоичном виде от датчиков-рецепторов, и рассматривает процесс ее последующего агрегирования и усложнения. Диапазон знаний, обрабатываемых системой ААУ, может расширяться до пересечения с диапазоном знаний, обрабатываемых ЭС, при соответствующем количественном расширении УС ААУ и использовании указанных возможностей формирования языка, вербализующего элементы знания. Система ААУ работает на своего рода ″рефлекторном уровне″, набирая статистику по прецедентам пространственно-временных вариаций наблюдаемой информации и их связям с выходными воздействиями, не вдаваясь в содержательный смысл найденных закономерностей, а только оценивая их влияние на целевую функцию. Видимо, здесь уместна аналогия с ситуацией в нервной системе ребенка, когда он, например, осваивает езду на велосипеде, находя закономерные связи пространственно-временных образов, оценивая их качество, и запоминая полученные знания в своей памяти, затем использует их для управления. Применение ЭС в диапазоне знаний, соответствующих процессам на уровне рецепторов и нейронов нервных систем, вряд ли целесообразно, так как выходит из сферы предназначения ЭС по их определению и неэффективно по реализации. С точки зрения уровня автоматизации систем, система ААУ по своей идее полностью автоматическая автономная система, работающая без участия человека и реализующая в реальном времени процесс обучения и управления. ЭС по своей идее средство автоматизации представления знаний, накопленных человеком-экспертом, и использования этих знаний человеком в режиме консультирования.
С точки зрения способов реализации, наиболее органичным для системы ААУ способом является нейросетевой подход в его аппаратном воплощении, наиболее адекватном строению естественных нервных систем. Подходы к реализации ЭС по способам ″представления знаний″ и ″рассуждений″ ориентированы на программные реализации. Общие черты в системе ААУ и ЭС можно увидеть в наличии в составе обеих систем блоков распознавания образов, представления знаний, принятия решений, что характерно для многих автоматических или полуавтоматических управляющих систем и интеллектуальных систем. Сближение подходов ЭС и ААУ будет происходить по мере появления в ЭС следующих свойств: способности работать в автоматическом режиме и в режиме реального времени, ориентации на работу с элементарной сенсорной информацией, переходу к автономным способам использования, что, вообще говоря, входит в противоречие с исходным назначением ЭС. Системы ААУ могут приближаться к свойствам ЭС, если разрушить их автоматический принцип действия и перевести на полуавтоматический режим работы в качестве системы поддержки принятия решений. 5.3. Метод ААУ и системы нечеткой логики В последнее время широкое развитие получают управляющие системы на основе нечеткой логики (fuzzy logic), т.е. логики, в которой используются нечеткие квантификаторы. Системы принятия решений на этой основе используют рассуждения (т.е. способы получения заключений или новых знаний) с подобными квантификаторами с помощью специальных приемов. Системы с использованием нечеткой логики были специально разработаны для решения плохо определенных задач и задач с использованием неполной и недостоверной информации. Обоснованием такого подхода является подмеченное свойство мозга, состоящее в том, что человек в процессе принятия решений почти всегда пользуется именно неполной и недостоверной информацией. Это свойство мозга заключено, по-видимому, в свойствах самих нейронов и их сети. Обученный нейрон способен противостоять помехе во входном векторе и, тем самым, пользуется неполной и недостоверной входной информацией для принятия решения о генерации выходного сигнала – спайка.
96 Аналогами нечетких квантификаторов, по всей видимости, являются размеры синапсов, пропорциональные частоте использования данного входного сигнала, и косвенно отражающие его достоверность. В формальных нейронах в методе ААУ (см. часть 1) используется порог, определяющий полноту входного вектора, достаточную для его восприятия нейроном (этот порог уменьшается с накоплением статистики по данному сигналу). По сути, наличие этого порога приводит к тому, что сеть таких нейронов в системе ААУ работает в режиме определенной нечеткой логики. Таким образом, те свойства нервных систем, которые явились объектом моделирования в системах нечеткой логики, присутствуют в сетях нейронов системы ААУ. Безусловно, наработки теории нечеткой логики могут быть использованы в системе ААУ в отдельных ее подсистемах, особенно при создании приложений. Заметим, что как и в случае ИНС, системы нечеткой логики выделяют и эксплуатируют только одно из свойств мозга. Целью методологии ААУ является построение концептуальной модели нервной системы как целого. Заключая данный раздел, необходимо отметить следующее. Как было показано выше, всякая управляющая система находится в цикле управляемого взаимодействия с объектом управления и средой (см. рис.7). Управляющая система, которая претендует на имитацию мозга, должна состоять из определенных подсистем – аппарата формирования и распознавания образов, базы знаний, аппарата эмоций, аппарата принятия решений, которые принадлежат названному циклу прохождения информации. Очевидно, что в разных приложениях в зависимости от условий имеются возможности сильного упрощения отдельных подсистем такой полной управляющей системы или их замены ″заглушками″, при этом сам цикл управляемого взаимодействия может сохраняться. Соответственно, центральная задача о построении автономной адаптивной системы управления в общем виде существенно изменяется и возникают частные постановки задач и планы их решений. 1. Если априори достоверно известно, как следует управлять в той или иной ситуации, а вся проблема состоит только в правильном распознавании ситуации,
то УС можно построить на основе системы распознавания, разработка которой и потребует основных усилий. Роль остальных подсистем в УС (рис. 7) становится элементарной. Здесь для построения УС потребуются знания теории распознавания образов. Если при этом задача распознавания плохо формализуется, но имеется обучающая выборка, то можно использовать нейросети. Бытует соответствующее мнение, что вся проблема управления может быть сведена к проблеме распознавания. 2. Если для управления требуется только использовать удобным образом представленные знания, накопленные ранее, а все остальные подзадачи решены и данные определены, то в составе УС на первое место выдвигается база знаний, а остальные подсистемы вырождаются. Проблема сводится к способам представления знаний, автоматизации вывода новых знаний из уже имеющихся, интерпретации полученных выводов и т.д. В этом случае УС можно построить на основе экспертной системы с соответствующим упором на решение проблем получения, представления и использования знаний. 3. Если ни задача распознавания, ни задача получения и представления знаний в управляющей системе не актуальны, т.е. все данные и решения для этих блоков УС определены, а проблема состоит только в принятии оптимальных решений на основе текущей информации и имеющихся знаний, то проблема построения УС превращается в задачу выбора и принятия решений с применением соответствующих подходов. В частности, при чрезмерной сложности строгих процедур принятия решений, возможно применение робастных подходов или систем нечеткой логики. Если зависимости не слишком сложны, но вид их известен, а надо только найти подходящие значения параметров, используются параметрические подходы к построению адаптивных систем управления, возможны и непараметрические случаи для зависимостей произвольного вида. 4. Если известны все данные и все возможные решения для всех подсистем УС, заданы некоторые критерии, определяющие требования к УС и ее качество, и ставится задача добиться наибольшего качества работы системы, то появляется необходимость в
97 применении системы.
методов
оптимизации
Заметим, что названные здесь отдельные задачи к настоящему времени очень глубоко осмыслены и имеют свои решения. На основе этих решений строятся очень эффективные системы. Некоторые из предложенных решений не имеют никакого отношения к моделированию мозга и нервных систем, некоторые имеют, но относятся к так называемому ″программнопрагматическому направлению″, моделирующему только конечный результат (например, распознающие системы, экспертные системы, системы нечеткой логики), некоторые относятся к ″имитационному″ направлению, моделирующему и результат и принцип решения (например, нейросети). Однако даже системы, моделирующие деятельность мозга, вычленяют только какое-то одно его частное свойство, хотя моделирование этого свойства может оказаться настолько полезным, что на его основе удается строить действующие технические системы, эффективно решающие некоторый соответствующий им класс задач. Можно утверждать, что для любого подхода такого рода всегда найдется приложение, в котором этот подход даст оптимальное решение. Сравнение таких решений даже с решениями мозга человека часто оказывается не в пользу последнего. Например, автопилот способен пилотировать самолет более качественно, чем летчик, но только в отдельных режимах. Система принятия решений может лучше человека играть в шахматы, но решать только эту задачу. Экспертная система может обладать знаниями в некоторой предметной области, которые превосходят знания любого специалиста. Система логического вывода может лучше человека доказывать теоремы. Но каждая из таких систем по принципу действия, а также по своим функциям не соответствует мозгу как таковому. Вопрос о моделировании мозга остается открытым. Целью методологии ААУ является построение именно концептуальной модели нервной системы. В каждом из этих частных решений, подменяющих задачу построения автономной адаптивной системы управления в общем виде задачей построения только одной из ее подсистем, присутствуют определенные исходные данные, заслоняющие и подменяющие собой все другие подсистемы. Теперь
представим ситуацию, когда не определены или плохо определены данные для всех подсистем УС. Например, УС ″видит″ входные данные, но не видит в них никаких закономерностей, а если какие-то закономерности обнаружила, то не понимает, хорошо это для нее или плохо, не видит разницы между вариантами действий, выполнение которых она может инициировать, не видит связи между своими действиями и поступающей на вход информацией, а если видит, то не умеет использовать, а если умеет, то не понимает с какой целью, а если понимает, то не всегда успевает, и т.д. (читатель может проанализировать свой собственный опыт, когда он оказывался в незнакомых условиях, что типично для всех биологических систем). Анализ именно этой ситуации, а также поиск решений и есть предмет исследования методологии ААУ. По видимому, эта задача комплексного построения системы, работающей в названных условиях, отличается от задач, перечисленных выше в пунктах 1-4 и не сводится к ним. Как минимум, речь идет о поиске взаимосогласованного решения всего комплекса названных задач. Отсюда можно сделать вывод, что вопрос о сравнении системы ААУ и перечисленных выше ″альтернативных″ систем аналогичен попытке сравнить некоторую цельную систему, собранную из подсистем, с каждой из таких подсистем взятых отдельно. В завершение необходимо сказать, что при постановке задачи построения системы автономного адаптивного управления в общем виде имеется проблема философского плана. Нужны ли такие управляющие системы, где может понадобиться искусственная нервная система? В научно-техническом развитии набрана большая инерция разработки и использования именно частных случаев управляющих систем. От автоматических устройств требуется только быть точными исполнителями строго определенных заданий. Нужна ли кому-нибудь саморазвивающаяся, имеющая собственное целеполагание и внутреннюю активность, совершающая пробные поисковые движения, обладающая собственными эмоциями, зависящая от случайностей в своей предыстории управляющая система? Чтобы оценить возможности практического использования искомой совершенной модели какой-либо нервной системы в случае ее создания (например, нервной системы мыши), достаточно представить
98 себе возможности практического использования оригинала – живой мыши. Поиск сферы практического использования таких систем в их полном виде нетривиален. Системы, обладающие свойствами рассмотренных систем ААУ, не соответствуют общепринятому пониманию и назначению систем искусственного интеллекта (ИИ), к которым сегодня относят экспертные системы, распознающие системы, нейросети, лингвистические процессоры и робототехнику. Поэтому предлагается выделить системы с подобными свойствами в отдельное направление ″Системы автономного искусственного интеллекта″ (АИИ) [13]. Если основное назначение систем ИИ - быть исполнителями заданий, поступивших извне от пользователя, то назначение систем АИИ – выживать и накапливать знания, подчиняясь более свободному от внешних управляющих воздействий внутреннему целеполаганию. Помимо теоретического интереса, прагматическое значение систем АИИ, имитирующих естественные организмы, может состоять в их способности к выживанию, работе и накоплению знаний в плохо формализуемых условиях, требующих адаптации и саморазвития.
6. Заключение В настоящей работе был с минимальным математическим формализмом изложен возможный подход к решению фундаментальной проблемы построения имитационной модели нервной системы, названный методологией автономного адаптивного управления (ААУ). Прагматическое значение рассмотренного подхода состоит в том, что он позволяет строить действующие, хотя и со сравнительно небольшим пока числом (~104-105) образов, но практически полезные быстродействующие адаптивные управляющие системы, пригодные для управления объектами, плохо поддающимися формализации. Приведены примеры простых прототипов практических приложений систем. Показано, что по мере увеличения возможного числа эмулируемых нейронов, а также по мере решения проблем перехода от континуальных величин к дискретным, ″интеллект″ системы ААУ может существенно возрастать. Проведен сравнительный анализ систем ААУ с альтернативными подходами к построению управляющих систем. Утверждается, что
системы ААУ могут составить самостоятельное направление ″системы автономного искусственного интеллекта (АИИ)″, имеющее свое назначение и сферу применения. 6.1 Направления дальнейших исследований Дальнейшее развитие метода ААУ планируется вести по следующим трем основным направлениям: имитационному, прагматическому и прикладному. 1. В имитационном (бионическом) направлении предполагается: а) развитие общей структуры управляющей системы и структуры ее подсистем; б) развитие возможностей преобразования континуальных параметров в дискретные с помощью нейроноподобных подсистем; в) развитие формальных нейронов с целью приближения их свойств к свойствам биологических нейронов. 2. В прагматическом направлении предполагается: а) исследование представляемости функций с помощью нейроноподобных сетей из описанных формальных нейронов. В частности, представляемость пространственновременных прообразов нейросетевой подсистемой формирования и распознавания образов (ФРО) и представляемость знаний нейросетевой базой знаний (БЗ) управляющей системы ААУ; б) разработка методики построения управляющей системы ААУ на основе априорной информации об объекте управления. В частности, выработка точных правил определения топологии и параметров нейросетей, образующих управляющую систему. 3. В прикладном направлении предполагается разработка практических приложений в различных отраслях и разработка методики создания систем. В разработке отдельных вопросов и приложений метода ААУ принимали участие С.В. Яговкин, В.Н. Полунин, А.Н. Винокуров, А.В. Рядовиков. Литература 1. Винер Н. Кибернетика, пер. с англ., 2 изд. М., 1968. 2. Cannon, W.B. Bodily Changes in Pain, Hunger, Fear and Rage.// Appleon-Century, 1929. 3. Анохин П.К. Теория функциональной системы. Тр. международного симпозиума по техническим и биологическим проблемам управления (Ереван, 24-28 сент.1968 г.). Общие вопросы
99
4.
5. 6.
7. 8. 9.
10.
11.
12.
13.
14.
15.
16.
17.
физиологических механизмов. Анализ и моделирование биологических систем// М.: Наука, 1970. Ляпунов А.А., Беликова М.А. О кибернетических вопросах биологии. - В кн.: О некоторых вопросах кодирования и передачи информации в управляющих системах живой природы// Новосибирск, 1971. Mesarovic M.D. Conceptual basic for a mathematical theory of general systems// Kybernetes, 1, 1972. McCulloch W.S., Pitts W. A logical calculus of the ideas immanent in nervous activity// Bull. Math. Biophys. 1943, 5. [Русс. пер.: Маккалок У., Питтс У. Логическое исчисление идей, относящееся к нервной активности. - В сб. Автоматы.-М.: ИЛ, 1956.] Розенблат Ф. Принципы нейродинамики// М.: Мир, 1965. Жданов А.А. О подходе к моделированию управляемых объектов. Пpепpинт ВЦ РАH СССР, М., 1991. Zhdanov A.A.. Application of Pattern Recognition Procedure to the Acquisition and Use of Data in Control.// Pattern Recognition and Image Analisis vol.2, N2,1992. (ISSN: 1054-6618). Zhdanov A.A.. A principle of Pattern Formation and Recognition.// Pattern Recognition and Image Analisis vol.2, N3,1992. (ISSN: 10546618). Жданов А.А. Об одном имитационном подходе к адаптивному управлению. Сб. "Вопросы кибернетики". Научный совет по комплексной проблеме "Кибернетика" РАН. Вып. 2. М., 1996. Жданов А. А. Формальная модель нейрона и нейросети в методологии автономного адаптивного управления. Сб. "Вопросы кибернетики". Научный совет по комплексной проблеме "Кибернетика" РАН. Вып. 3. М., 1997. Жданов А.А. О понятии автономного искусственного интеллекта // Сб. научн. тр. Искусственный интеллект в технических системах. - М.: Гос.ИФТП. 1997. Zhdanov A. A. About an Autonomous Adaptive Control Methodology. ISIC/CIRA/(ISAS'98), NIST, Gaithersburg, Maryland. September 1417, 1998. Zhdanov A. A. The Mathematical Models of Neuron and Neural Network in Autonomous Adaptive Control Methodology. WCCI’98(IJCNN’98), IEEE World Congress on Computational Intelligence, Anchorage, Alaska, May 4-9, 1998. Жданов А. А., Норкин Н. А., Гуриев М. А. Некоторые практические приложения метода автономного адаптивного управления // Сб. научн. тр. Искусственный интеллект в технических системах. Вып. 19.- М.: Гос.ИФТП. 1998. Жданов А. А., Винокуров А. Н. Система проектирования и исследования нейронных сетей ″СПИНС″ в методологии автономного
18.
19.
20.
21. 22. 23.
24.
адаптивного управления // Сб. научн. тр. Всероссийской научн.-техн. конференции ″Нейроинформатика-99″, ч. 1. - М.: МИФИ. 1999. Рядовиков А. В., Жданов А. А., О некоторых формальных моделях нейронов. // Сб. научн. тр. Всероссийской научн.-техн. конференции ″Нейроинформатика-99″, ч. 1. - М.: МИФИ. 1999. Жданов А. А., Арсеньев С.В. О некоторых приложениях принципа автономного адаптивного управления // Сб. научн. тр. Всероссийской научн.-техн. конференции ″Нейроинформатика-99″, ч. 3. - М.: МИФИ. 1999. Жданов А. А., Винокуров А. Н. О нейросетевом методе ″Автономного адаптивного управления″, Сб. докл. Пятой Всероссийской конференции ″Нейрокомпьютеры и их применение (НКП-99)″. М., 17-19 февраля 1999. http://www.ispras.ru/~zhdanov/ Чечкин А.В. Математическая информатика. – М.: Наука, 1991. Hopfield J.J. Neural networks and physical systems with emergent collective computational abilities. Proc. of the National Academy of Science 79: 2554-58. 1982. Bernold T., Expert Systems and Knowledge Engineering. Elsevier, Science Publishers, 1986.
Распределенные объектно-ориентированные системы В.П. Иванников, К.В. Дышлевой, С.Г. Манжелей, Л.Б. Соловская, А.Б. Шебуняев
Аннотация Группа "Распределенные объектноориентированные системы" существует в ИСП РАН с осени 1995 года. Научные интересы группы связаны с распределенной обработкой в неоднородных средах и созданием унифицированной среды для разработки и выполнения распределенных объектно-ориентированных приложений. В частности, рассматривается применение объектно-ориентированного подхода для создания распределенных систем, активные и пассивные объектные модели, метаобъектные протоколы, построение распределенных информационных систем. Со времени создания группа участвовала в нескольких проектах по заказам компаний Nortel Networks, Biomax Informatics GmbH и работах, поддерживаемых Российским Фондом Фундаментальных Исследований (РФФИ). Были разработаны брокеры объектных заявок для языков C++ и Protel2, предложена методология построения распределенных систем на основе модели оболочки, в стадии реализации находится информационная система для биологических банков данных.
1. Введение Совpеменные пpогpаммные системы создавались и создаются в условиях существенной неодноpодности и pаспpеделенности пpогpаммной сpеды. Pеализационная неодноpодность опpеделяется истоpическим, эволюционным pазнообpазием платфоpм, сpедств и моделей пpогpаммиpования. Инфоpмационная неодноpодность связана с pазнообpазием пpикладных контекстов, способов абстpакций и степенью пpиближения к моделиpуемым объектам и пpоцессам pеального миpа. Развитие сетевых технологий предоставило удобную инфраструктуру для разработки больших распределенных программных комплексов. А потpебность в pаспpеделенной обpаботке пpивела к появлению технологии создания интеpопеpабельных инфоpмационных систем.
Под интеpопеpабельностью понимается способность совместной, согласованной деятельности pазноpодных компонент системы для pешения опpеделенной задачи. Основу инфоpмационной аpхитектуpы интеpопеpабельных систем составляет концепция пpомежуточного слоя (middleware). Интероперабельность достигается введением общего механизма поддеpжки взаимодействия компонентов (например, бpокеpа объектных заявок), введением общей базовой модели компонентов (как пpавило, объектной), унифициpованного языка спецификаций интеpфейсов, отделением pеализации компонентов от спецификации их интеpфейсов. Тем самым достигается одноpодность пpедставления компонентов и их взаимодействия. Для полноты инфоpмационной аpхитектуpы также вводится слой унифициpованных оpтогональных служб, констpуиpуемых по тем же пpинципам, что и обычные пpиложения. Распределенные технологии находят применение при построении больших систем с повышенными требованиями к надежности, быстродействию, открытости. К таким системам можно отнести телекоммуникационные программные комплексы, системы реального времени, информационные системы. Для создания сложных систем с множеством межкомпонентных связей широкое распространение получили объектные технологии. К достоинствам объектного подхода можно отнести естественную декомпозицию предметной области на объекты в сочетании с инкапсуляцией данных, опpеделение интеpфейсов между компонентами, возможность рассматривать систему на разных уровнях абстракции, потенциальную возможность повторного использования как функциональности, так и архитектуры системы (полиморфизм, наследование). Такие крупные международные организации, как международный комитет по стандартизации International Organization for Standardization (ISO), консорциумы Object Management
101
Group (OMG) и Telecommunications Information Network Architecture – Consotium (Tina-C), компания Microsoft, приняли объектно-ориентированную парадигму за основу своих распределенных технологий. Развитие распределенных технологий сопровождается разработкой открытых стандартов, активно поддерживаемых разработчиками программных продуктов. На настоящий момент наиболее популярны следующие промышленные стандарты на программное обеспечение промежуточного слоя: Common Object Request Broker Architecture (CORBA) консорциума OMG, Distributed Component Model (DCOM) компании Microsoft, Telecommunications Information Network Architecture (TINA) консорциума Tina-C. Определенным ограничением перечисленных стандартов можно считать недостаточно последовательный подход к поддержке единой среды разработки и выполнения распределенных приложений. Как правило, в стандартах предлагается спецификация набора слабо связанных между собой сервисов (например, сервисы именования, конкурентного доступа), которые могут использоваться во время выполнения приложения, а этап разработки просто не рассматривается. Разработка конкретных проектов, связанных с построением распределенных систем, показала необходимость использования единой среды создания и выполнения распределенных приложений. Также в процессе работы был выявлен ряд недостатков, связанных с надежностью программирования и эффективностью выполнения распределенных приложений. Предложениям по решению этих и других проблем, связанных с программированием в распределенных средах, посвящена основная часть этой статьи. Оставшаяся часть статьи имеет следующую структуру. Второй раздел посвящен задаче построения унифицированной среды разработки и функционирования распределенных приложений и ряду проблем, возникающих при этом. В третьем разделе более подробно рассматриваются конкретные проекты, реализованные группой. Эти проекты связаны с разработкой коммуникационного программного обеспечения для использования в распределенных телекоммуникационных системах и разработкой информационнопоисковой системы для биологических банков данных. Четвертый раздел статьи
посвящен научным интересам группы, а именно, использованию метаобъектных протоколов для создания среды проектирования и выполнения распределенных приложений, рассмотрению активных объектных моделей, подходам к оптимизации процедур маршалинга, проблемам адаптации унаследованного кода в CORBA-среду. В заключении подводятся некоторые итоги и рассматриваются возможные направления исследований в области распределенных вычислений.
1. Среда разработки и выполнения распределенных объектноориентированных приложений Для поддержки всего жизненного цикла распределенной системы предполагается наличие единой среды разработки и выполнения распределенных объектноориентированных приложений. Такая среда должна предоставлять расширяемый набор системных сервисов, которые могут прозрачным образом подключаться к объектам приложения и таким образом расширять их прикладную функциональность. Помимо этого, среда должна обеспечивать согласованное взаимодействие распределенных контекстов, в которых существуют объекты приложения. Для поддержки функционирования распределенной системы, а также для обеспечения возможности прозрачного подключения системных сервисов, необходим механизм взаимодействия объектов, отвечающий требованию позднего связывания. Техника позднего связывания подразумевает, что клиент получает объектную ссылку на серверный объект с помощью системного окружения уже во время выполнения приложения. Примером механизма, обеспечивающего необходимый стиль взаимодействия объектов, может служить брокер объектных заявок, используемый в архитектуре CORBA (OMG) [CORBA98]. По заказу компании Nortel Networks для использования в проекте по созданию открытых телекоммуникационных систем группой были разработаны брокеры для языков C++ и Protel-2. Телекоммуникационные системы предполагают высокую надежность, быстрое время реакции, отказоустойчивость, параллельное обслуживание множества запросов. Постоянная эволюция и внедрение новых технологий, необходимость поддержки работающих унаследованных программ делает необходимым построение систем с
102
открытой архитектурой, способных функционировать в распределенных неоднородных средах. Промышленный стандарт промежуточного слоя CORBA широко применяется для построения открытых распределенных систем в телефонии. Использование механизма брокера объектных заявок позволяет взаимодействовать компонентам системы, реализованным на разных платформах и, возможно, в разных объектных моделях. Как и большинство стандартов на архитектуру распределенных систем, стандарт CORBA предусматривает спецификацию набора системных сервисов (например, сервисы именования, поддержки жизненного цикла объектов, конкурентного доступа). Но, как правило, эти сервисы разрабатываются изолировано друг от друга, а их функциональность частично пересекается. Более совершенная схема предполагает наличие единой среды разработки и выполнения распределенных объектно-ориентированных приложений, предоставляющей потенциально расширяемый набор ортогональных сервисов. Подключение сервисов, по возможности, должно происходить прозрачным для приложений образом. Принцип ортогональной декомпозиции особенно важен для возможности независимой разработки и подключения сервисов, а, следовательно, и для систематического расширения системы. В рамках работы была предложена модель оболочки, обеспечивающая прозрачное подключение сервисов и согласование распределенных контекстов на основе метаобъектных протоколов (МОП) [IVDKMS97]. Техника метаобъектного контроля и рефлексии уже широко используется для проектирования гибких, динамически адаптивных программных систем в объектноориентированном программировании. Но, как правило, метаобъектный контроль применяется либо на фазе проектирования, либо на фазе выполнения. Однако наиболее естественным и удобным представляется использование метаобъектных протоколов на всех этапах жизни программной системы. Постановка такой задачи требует достаточно эффективной реализации механизма МОП. Одна из возможных реализаций на основе интерфейсных объектов была предложена и будет более детально рассмотрена в четвертом разделе этой статьи. В процессе реализации брокера объектных заявок для языка С++ был
обнаружен ряд недостатков в работе с отображением из языка спецификаций OMG Interface Definition Language (IDL) в язык реализации С++. Был предложен новый подход, основанный на оболочкахпосредниках, обеспечивающих надежную схему работы с памятью [Dysh97]. Как показали дальнейшие исследования, использование таких посредников предоставляет технологическую базу для “прозрачного” расширения функциональности приложений и, в частности, для реализации МОП. В распределенных системах неизбежно возникает необходимость преобразовывать данные из одного формата в другой. В связи с увеличением быстродействия компьютерных сетей становится актуальным построение эффективных протоколов для передачи данных в гетерогенных средах. При реализации брокера для языка C++ были рассмотрены различные подходы к оптимизации процедур преобразования данных (маршалинга), позволяющие реально увеличить скорость взаимодействия распределенных объектов [DKS97]. Как и любая другая технология, распределенные объектные технологии сталкиваются с проблемой использования унаследованного кода. Принцип отделения интерфейсов от реализаций предоставляет для этого определенные технологические возможности. При разработке брокера объектных запросов для языка Protel-2, предназначенного для работы в специализированной среде главного модуля телекоммуникационной системы, возникла необходимость учитывать уже существующий, унаследованный код. В частности, требовалось включать в порождаемый компилятором код уже существующие модули реализации, использовать нестандартные имена. Для поддержки унаследованного кода был предложен подход, расширяющий возможности стандартного отображения из IDL в язык реализации [KMS97]. Также были рассмотрены возможности автоматизации процесса адаптации унаследованного кода (в частности, порождение спецификаций интерфейсов по коду реализаций). Наряду с традиционными пассивными моделями, определенный класс задач предполагает использование моделей активных объектов, более точно отражающих реальную действительность. Поэтому среда разработки и выполнения распределенных систем должна предоставлять возможность согласованного
103
взаимодействия активных и пассивных объектов, поддержку синхронных и асинхронных вызовов, их динамическую трансформацию. В процессе исследовательской работы был рассмотрен ряд известных активных моделей, предложена их классификация и на ее основе предложена метамодель, позволяющая, с одной стороны, предоставить программисту уже освоенные средства, заимствованные из предшествующих моделей, а с другой стороны, освободить его от решения типичных проблем и по возможности защитить от ошибок программирования. Разработка брокеров объектных заявок, исследования, направленные на повышение надежности и эффективности программирования с использованием брокеров, тем или иным образом связаны с разработкой элементов единой среды разработки и функционирования распределенных приложений. Построение информационной системы для биологических банков данных является реальным примером создания именно такого распределенного объектноориентированного приложения. Эта информационная система создается на базе архитектуры CORBA c использованием брокера объектных заявок для языка C++ и стандартных системных сервисов. Необходимость совместного использования сервисов (в частности, сервиса именования и сервиса жизненного цикла объектов), потребность согласовывать действия клиента и сервера подтвердили необходимость унифицированной среды для поддержки распределенных вычислений.
3. Проекты распределенных систем 3.1. Телекоммуникационные системы Использование распределенных технологий в телефонии объясняется спецификой предметной области: большое количество клиентов, обслуживаемых одновременно, требования к надежности, отказоустойчивости, времени реакции системы. Подключение новых сервисов, большой объем унаследованных программ, потенциальное развитие и внедрение новых технологий в уже работающую систему предполагает построение систем с открытой архитектурой. Модуль, непосредственно выполняющий обработку телефонных звонков в режиме реального времени, в телекоммуникационных системах, как правило, реализован и
выполняется на определенной платформе. Например, Digital Multiplex Switch (DMS), Nortel Networks, работает на специальном процессоре Compute Module (CM) под управлением операционной системы SOS. В простейшем случае все сервисы (секретности, авторизации, аутентификации и т.д.) могут разрабатываться в этой же среде. Но со временем разработка новых сервисов становится слишком сложной и дорогой операцией как из-за недостаточной инкапсуляции функциональности DMS, так и из-за невозможности выполнения всех сервисов на одной платформе. Проекты создания открытых систем в телефонии (например, проект Open Node для Nortel Networks) ставят своей целью пошаговую разработку пользовательских сервисов и расширение функциональности главного модуля на стороне заказчика (или на "третьей" стороне). При этом существенно, что сервисы могут быть прототипированы и реализованы на разных платформах, наиболее полно отвечающих требованиям той или иной задачи. Это, позволяет, во-первых, разгрузить основной модуль и, во-вторых, более гибко и удобно адаптировать систему для конкретного заказчика. Независимая разработка сервисов упрощает управление системой в целом и внедрение новых технологических решений. Применение объектно-ориентированного подхода в сочетании с той или иной распределенной технологией позволяет объединять сервисы, внешние по отношению к главному модулю и его среде, в единую интероперабельную систему, обеспечивая сервисам доступ к главному модулю в виде вызова удаленных объектов. Создание открытых систем предполагает наличие открытых интерфейсов, специфицированных на уровне международных промышленных стандартов. Наличие таких стандартов обеспечивает гибкость и переносимость прикладных программ в рамках определенной технологии. В области телекоммуникационных систем существует ряд собственных стандартов и подходов. Например, технология Computer Telephony Integration (CIT) определяет интерфейсы прикладного программирования (API) для интеграции программного обеспечения с телекоммуникационным оборудованием. Среди предложенных в CIT стандартов и решений можно назвать Telephony Application Programming Interfaces (TAPI), реализованный компанией Microsoft, Analog Display System Interfaces (ADSI), NetWare Telephony Services
104
Application Programming Interfaces (TSAPI), реализованный компанией Novell, Signal Computing System Architecture Telephony Application Objects (SCSA TAO). Одной из наиболее известных международных организаций, занимающихся разработкой телекоммуникационных систем, является консорциум TINA-C, образованный в 1993 году и объединяющий более 40 производителей телекоммуникационного обеспечения. Деятельность консорциума связана с разработкой стандартов и технологий, позволяющих повысить переносимость сервисов, а также обеспечить возможность их повторного использования. Так как телефония является одной из самых перспективных областей для применения технологий создания интероперабельных систем, деятельность TINA-C оказывает большое влияние на формирование стандартов в области распределенных технологий (OMG CORBA, ITU, ANSA). 3.1.1 С++ ISP ORB В качестве базиса для построения интероперабельной системы, расширяющей функциональность модуля Digital Multiplex Switch (DMS) для Nortel Networks, был выбран подход, предложенный консорциумом Object Management Group (OMG). Деятельность консорциума OMG направлена на создание новых компьютерных технологий и стандартов. Консорциум объединяет более 200 компаний, занимающихся разработкой программного обеспечения. Архитектура компонентов пpомежуточного слоя Common Object Request Broker Architecture (CORBA) – одна из наиболее известных его pазpаботок. Технология брокеров объектных заявок позволяет приложениям, реализованным на разных платформах, взаимодействовать в неоднородных распределенных средах прозрачным по расположению объектов образом. В аpхитектуpе CORBA бpокеp игpает pоль "общей шины" в глобальном пpостpанстве объектов, выполняя опеpации нахождения объекта, его активации, пеpедачи паpаметpов и результатов. Взаимодействие между объектами стpоится по принципу клиент-сеpвеp, посредником между которыми является брокер объектных заявок. Объектная модель DMS включает такие понятия из проблемной области, как Call, Half Call, Party, Facility, Connection. Интерфейсы этих объектов определяются на языке OMG Interface Definition Language
(IDL). Независимая спецификация интерфейсов позволяет внешним сервисам обращаться к реализациям объектов, выполняющимся в среде DMS. В свою очередь, сервисы, удовлетворяющие определенным спецификациям и функционирующие на других платформах, могут быть вызваны объектами из среды DMS. Прозрачность по расположению объектов достигается путем использования специальных посредников (статических – стабов и скелетонов, или динамических). Протокол взаимодействия между брокерами General Inter-ORB Protocol (GIOP) является частью спецификации CORBA. Наиболее распространенной версией этого протокола является отображение GIOP на TCP/IP, называемое Internet Inter-ORB Protocol (IIOP) и также включенное в стандарт. Как уже говорилось выше, главный “телефонный” модуль, как правило, реализован на специализированной платформе и, следовательно, в его среде используется свой внутренний протокол взаимодействия. Поэтому реализация проекта по расширению функциональности модуля DMS включает использование двух брокеров. Брокер, расположенный непосредственно в среде DMS и использующий внутренний протокол, взаимодействует с внешними сервисами посредством другого брокера, использующего стандартный CORBA протокол. А специальный посредник (Bridge) преобразует сообщения из внешнего формата в формат внутренних сообщений DMS.
Рис. 1. Общая структура интерфейсов брокера объектных заявок В качестве “внешнего” брокера был разработан С++ ISP ORB, удовлетворяющий
105
стандарту OMG CORBA 2.1 [CORBA97] (рис. 1). Реализация включает непосредственно библиотеку брокера и компилятор, реализующий полное отображение из IDL в C++. Брокер поддерживает работу как со статическими посредниками (стабами и скелетонами), генерируемыми компилятором, так и с динамическими интерфейсами (Dynamic Interface Invocation, Dynamic Skeleton Invocation). Объекту в распределенном пространстве ставится в соответствие понятие объектной ссылки. Объектная ссылка инкапсулирует информацию о нахождении объекта с точки зрения конкретного брокера. Для передачи объектной ссылки между разными брокерами стандарт CORBA предусматривает преобразование в некоторое универсальное представление Interoperable Object Reference (IOR). Приложение имеет понятие об объектной ссылке в соответствии со стандартом отображения из языка IDL. Для языка С++ объектная ссылка это обычный указатель на объект. Таким образом работа с удаленными объектами ничем не отличается от работы с локальными, хотя в случае удаленного объекта указатель в действительности указывает не на сам объект, а на его посредника, передающего вызов брокеру для дальнейшей отработки. Но от приложения это скрыто, и можно говорить о прозрачности по расположению объектов. Общий механизм выполнения запросов происходит по известной схеме удаленного вызова процедуры (Remote Procedure Call, RPC). В применении к объектноориентированному подходу можно говорить об объектном RPC (ORPC). Код статических посредников, а также отображение типов и констант из IDLспецификации порождается компилятором и известны уже на этапе компиляции. Благодаря поддержке динамических интерфейсов во время выполнения программы могут конструироваться запросы к объектам, интерфейсы которых не были известны на этапе компиляции. Помимо базового механизма взаимодействия объектов на основе брокера объектных заявок, архитектура CORBA предусматривает использование ряда сервисов, интерфейсы которых также специфицированы в стандарте. В частности, для регистрации и поиска объектов в распределенном пространстве может быть использован сервис именования (Naming service). Любой объект, чтобы стать доступным брокеру и другим объектам,
должен быть зарегистрирован в сервисе именования. С помощью этого сервиса приложение может по имени объекта получить его объектную ссылку. Далее эта объектная ссылка может быть передана как параметр другим объектам. Сервис именования является одним из основных сервисов, без которых использование брокера становится затруднительным. В процессе реализации брокера ISP ORB был обнаружен ряд существенных недостатков отображения из языка спецификаций интерфейсов IDL в C++, затрудняющих работу программиста в рассматриваемой среде. Для решения проблемы повышения надежности программного обеспечения была предложена концепция оболочекпосредников, которая существенно упрощает программирование приложений в CORBA-среде. Важно отметить, что новый подход не является альтернативой стандарту. Система оболочек реализована в виде надстройки над произвольной системой управления объектами, удовлетворяющей стандарту CORBA 2.1. Подробнее этот подход будет рассмотрен в четвертом разделе статьи. В процессе создания брокера ISP ORB были рассмотрены два подхода к реализации процедур преобразования данных (маршалинга), основанные на технике интерпретации и компиляции соответственно. С учетом известных достоинств и недостатков методов предпочтение было отдано механизму компиляции, обеспечивающему большую эффективность работы системы. Возможность использования техники интерпретации сохранилась для работы с данными, типы которых не известны на этапе компиляции, и для случаев, когда компактность системы имеет решающее значение. Реализация брокера С++ ISP ORB удовлетворяет стандарту CORBA 2.1 и может быть использована независимо от рассматриваемого проекта. С++ ISP ORB поддерживает работу в нескольких режимах. Библиотека брокера может использоваться как в виде разделяемой библиотеки, так и непосредственно “собираться” вместе с приложением. Также брокер может работать как с использованием нитей (POSIX threads), так и без этого. Бета-версия брокера свободно доступна и может быть получена по адресу http://www.ispras.ru/~dkv/isp_orb/download/ ref_index.html.
106
3.1.2 Protel-2 ORB Примером разработки брокера объектных заявок для специализированной среды модуля телекоммуникационной системы может служить брокер для языка Protel-2, предназначенный непосредственно для работы в среде модуля Digital Multiplex Switch (DMS). Язык Protel является внутренним языком программирования DMS. Реализация брокера является распределенной относительно двух модулей – CM (Compute Module) и SDM, UNIX-системы, напрямую связанной с DMS и поддерживающей локальную систему сообщений (MTS). Эта распределенность прозрачна для сервисов, обращающихся к объектам DMS.
Рис. 2. Взаимодействие брокеров для языков C++ и Protel-2 Взаимодействие в среде DMS основано на собственном внутреннем протоколе передачи сообщений – DMS MTS. Специальный посредник (Bridge) преобразует сообщения из стандартного формата IIOP TCP/IP в DMS MTS и обратно (рис. 2). Для этого стандартные сообщения в формате General Inter-ORB Protocol (GIOP) “обертываются” дополнительными заголовками, в соответствии с типом сообщений. Новый протокол получил название DIOP (DMS Inter-ORB Protocol). Важно отметить, что реализация брокера “многопроцессная”, то есть запросы выполняются не последовательно, а параллельно в разных процессах SOS, что позволяет увеличить производительность и существенно уменьшить время реакции системы на запросы. Главный процесс брокера создается вместе с запуском DMS и существует постоянно. При установлении связи с “внешним” брокером создаются процессы времени взаимодействия, которые завершаются при разрыве соединения. При получении брокером запросов создаются отдельные серверные процессы для выполнения каждого запроса.
Взаимодействие между процессами основано на работе с сообщениями в формате операционной системы SOS. Как правило, сообщение содержит идентификатор типа сообщения, указание, по какому адресу должен быть отправлен ответ, и ряд параметров. В большинстве случаев параметром сообщения является указатель на память, содержащую некоторые данные. Главный процесс брокера использует единственный “почтовый ящик”, куда поступают все запросы. Основное назначение этого процесса – диспетчеризация приходящих сообщений, создание серверных и коммуникационных процессов, и передача сообщений между ними. Все эти действия не требуют больших временных затрат и обращений к другим сервисам и, следовательно, могут быть выполнены последовательно. Коммуникационные процессы существуют в паре: посылающему процессу соответствует получающий (receiving/sending processes). Создаются эти процессы либо при обращении клиентского процесса к удаленному объекту, либо при установлении связи с некоторым “внешним” брокером. Серверный процесс создается главным процессом брокера на базе модуля, содержащего скелетон вызываемого объекта. После создания серверный процесс сразу же получает соответствующее сообщение от главного процесса, декодирует его содержание (IIOPсообщение) и вызывает необходимый метод серверного объекта. Метод серверного объекта выполняется непосредственно в этом же процессе. После завершения выполнения метода серверный процесс записывает результат в предоставленную главным процессом память и посылает ему соответствующее сообщение и завершается. В терминах языка Protel работа с брокером включает использование модулей нескольких типов. Во-первых, это модули, содержащие функциональность самого брокера (главный процесс, процесс“слушатель”, процесс-“получатель” сообщений, процесс-“отправитель” и библиотека брокера). Во-вторых, это модули, сгенерированные компилятором, содержащие код посредников и отображения типов и констант, в соответствии с отображением из IDL и Protel-2. И, в-третьих, это пользовательские модули, непосредственно реализующие прикладную задачу. В свою очередь, пользовательские модули могут использовать библиотечный модуль брокера для доступа к функциональности самого
107
брокера и модули, сгенерированные компилятором и позволяющие манипулировать объектами, опубликованными в IDLспецификации. Для реализации брокера было разработано полное отображение из IDL в Protel-2 (объектный Protel), поддерживаемое соответствующим компилятором. Язык Protel является корпоративным языком Nortel Networks, и спецификация CORBA 2.1 не предусматривает стандартного отображения из IDL в Protel. Как правило, одна IDL-спецификация отображается в один модуль на языке Protel-2, содержащий реализации стабов и скелетонов, а также все необходимые определения. Модель языка Protel-2 достаточно сильно отличается от языка IDL, поэтому отображение включает ряд трюков. Например, Protel-2 не поддерживает вложенные области видимости и составные имена, используемые в IDL. Поэтому схема отображения имен из IDL в Protel реализована по примеру отображения из IDL в C. Составное имя в IDL отображается в “длинное” имя в Protel, которое конструируется из последовательности имен вложенных областей видмости. Также Protel поддерживает одиночную схему наследования объектов, тогда как IDL предполагает множественное наследование. И, следовательно, отображение включает преобразование из множественной модели наследования в одиночную. Такое преобразование неизбежно приводит к трансформации некоторых семантических зависимостей. Предложенный алгоритм позволяет сократить количество новых зависимостей в графе наследования. При разработке отображения из IDL в Protel-2 внимание было уделено исследованию проблем адаптации унаследованного кода в CORBA-среду. Использование специальных директив препроцессору – прагм (#pragma) позволило, не расширяя базового набора конструкций IDL, уточнять отображение в соответствии с имеющимся кодом реализации. Более подробно предложенная система прагм и возникающие проблемы при адаптации унаследованного кода будут обсуждены в четвертом разделе. 3.2. Информационные системы в биологии (BioмaxRS) Наряду с нарастанием объемов обрабатываемой информации, усложнением структуры информационных элементов
(графика, мультимедиа, Jаvа-приложения), одной из самых заметных тенденций, характерных для современных информационных систем, является использование распределенных технологий для объединения различных информационных систем в гетерогенные сети с унифицированным пользовательским интерфейсом на основе технологии "клиент-сервер". Другой характерной особенностью является использование каналов Internet и WWW-технологий для доступа к информационным системам и, как следствие, возможность использовать стандартные сетвые клиенты (browsers). Исследования в биологии связаны с анализом большого количество фактической информации. Эта информация хранится, как правило, в текстовом виде в различных биологических банках данных (например, MEDLINE, GenBank). С развитием Internet и WWW-технологий появилась возможность удобного удаленного доступа к этой информации. А технологии интероперабельных систем позволяют говорить о совместном использовании различных информационных систем и их функционировании в неоднородных информационных контекстах. Информационно-поисковая система для Biomax Informatics GmbH (BiomaxRS – Biomax Retrieval System) предназначена для работы с множеством биологических банков данных. Система предоставляет средства поиска и манипулирования банками данных (создание, удаление, наполнение, редактирование, индексирование), а так же средства администрирования системы в целом. BiomaxRS является распределенной объектной системой, построенной на базе архитектуры CORBA, с использованием C++ ISP ORB. Основные функциональные элементы системы имеют API, специфицированные на OMG IDL. Языком реализации ядра системы является С++, но технология CORBA предоставляет возможность работать с клиентами, реализованными на других платформах. Для управления объектами используются стандартные CORBA-сервисы. В частности, для поиска объектов в распределенном пространстве используется сервис именования (Naming service). Архитектура CORBA позволяет естественным образом работать с распределенными ресурсами. Различные банки данных могут храниться на разных машинах, что позволяет говорить о распараллеливании их обработки (поиск,
108
индексирование). Система BiomaxRS поддерживает работу с различными форматами биологических банков данных. В качестве средства нормализации и семантической интероперабельности данных используется язык eXtensible Mark-up Language (XML), работа по стандартизации которого происходит под эгидой консорциума W3 [XML99]. Классические информационнопоисковые системы используют текстовое представление данных и, следовательно, классические методы поиска. Наряду с внедрением новых типов данных (графика, мультимедиа) рассматриваются новые модели документов. Широкие возможности для организации поиска, обработки и передачи между приложениями слабоструктурированных данных предоставляет язык разметки XML. Документы на языке XML представляют собой файлы ASCII, содержащие текст и теги, идентифицирующие структуры внутри текста. Для информационных систем существенно то, что XML удобен для кодирования собственных типов данных с помощью общепринятых файловых форматов. Средства XML позволяют создавать новые языки для описания структур данных в конкретных предметных областях (химия, математика, биология). На основе XML разрабатываются различные средства манипулирования данными, например, язык запросов XQL (аналог SQL для XML данных), язык XSL, позволяющий специфицировать отображения XML в HTML и другие представления. Без использования единого формата данных (например, языка XML) система, работающая с разными форматами данных, вынуждена использовать разные алгоритмы для извлечения необходимой информации из текстов. Используя XML, система работает только с информацией, представленной в виде XML-документов, имеющих определенную структуру. Это существенно упрощает обработку данных. При этом семантически одинаковые части различных форматов выделяются на этапе перевода в XML и преобразуются к единому виду. Например, информация о датах, представляемая в разных форматах данных по-разному (например, 1-JAN-98, 01/01/1998 или 1998, 1 january), в XMLдокументе имеет единый вид: .
Использование
XML
в
качестве
внутреннего представления данных объясняется еще и тем, что в скором будущем XML обещает стать международным стандартом. Консорциум W3 осуществляет активную деятельность, направленную на стабилизацию спецификаций XML, что вдохновляет разработчиков на создание приложений на его основе. Исходя из этих прогнозов, XML может стать средством обмена данными с информационными системами, внешними по отношению к BiomaxRS, но также использующими XML. Кроме того, уже сейчас существует множество инструментальных средств и технологий для работы с XML-документами. Например, для простейшей визуализации XMLдокумента может использоваться стандартный браузер Internet Explorer 5.0. В рамках объектной системы для манипулирования XML-документами удобно также использовать объектноориентированный подход. То есть компоненты системы взаимодействуют с XML-документом как с объектом. Соответствующие методы этого объекта предоставляют возможность создавать, удалять и редактировать части документа. Существует стандарт отображения XML структуры на объектную модель – Document Object Model (DOM), также поддерживаемый консорциумом W3. Имея IDL-интерфейсы (а спецификация DOM использует именно OMG IDL), такие объекты могут обрабатываться и в распределенной среде посредством CORBA. Поскольку XML основан на текстах в формате ASCII, он может использоваться для более эффективного обмена данными по сравнению с бинарными технологиями обработки сообщений (CORBA, DCOM). В частности, в подходе CORBA естественным способом передачи объекта является передача его “по ссылке” (то есть, реально передается объектная ссылка, а не сам объект). Передача объекта “по значению” требует дополнительных усилий, например использования системных сервисов (Persistent Object Service или Externalization Service). Сочетание XML и CORBA позволяет продуктивно использовать возможности обеих технологий для создания более гибкой распределенной среды. Единственным спорным моментом при использовании XML для управления информационным наполнением системы является необходимость предварительного переформатирования данных в XMLформат. Но преимущества использования
109
XML-документов окупают этот недостаток.
Рис. 3. Общая архитектура системы Общение пользователя с информационной системой (рис. 3) происходит с помощью стандартного HTML-браузера, который получает HTMLдокументы от web-сервера, связанного с ядром системы. WWW-интерфейс предоставляется не только конечным пользователям, использующими поисковые возможности системы, но и для администрирования системы. Web-сервер взаимодействует с ядром информационной системы посредством CORBA и создает HTML-документы на основе результатов запроса. Ядро системы разработано в рамках технологии CORBA и имеет распределенную архитектуру. В соответствии с их функциональностью, в ядре системы можно выделить три части: утилита для работы с форматами (Format Tool), утилита для работы с базами данных (Data Base Tool) и поисковая часть системы (Retrieval System). В рамках системы используется несколько внутренних представлений данных. Это, во-первых, XML-документы, получаемые из исходных “плоских” файлов с биологическими данными, а так же таблицы реляционных баз данных. Поисковая часть системы работает также с индексами, словарями и списками псевдонимов.
Основная функциональность системы связана с поиском и просмотром биологических данных и, следовательно, основная задача – это показ требуемого XML-документа пользователю. С точки зрения внутренних компонент системы, XML-документ- это объект, имеющий IDLинтерфейс (в соответствии со спецификацией DOM), и работа с ним осуществляется посредством CORBA. Для передачи такого объекта web-серверу (именно по значению, а не по ссылке) используется текстовое представление XML-документа. А web-сервер, в свою очередь, используя анализатор XML, преобразует XML-документ в HTMLстраницу. Рассмотрим подробнее составные части ядра системы. 3.2.1 Утилита для работы с форматами (Format Tool) Эта часть системы обеспечивает работу с различными форматами данных. В качестве исходной точки для информационного наполнения системы служат так называемые “плоские” файлы, получаемые из других биологических банков данных. Как правило, каждый банк использует собственный формат для представления данных. В системе BiomaxRS для каждого такого формата используется специальный транслятор, преобразующий исходный файл в XMLдокумент определенной структуры. Добавление в систему нового формата связано с добавлением нового транслятора, полученного с помощью компилятора форматов. На вход компилятору подается описание формата, а на выходе получается исходный код на C++ соответствующего транслятора. Для спецификации форматов был разработан язык, позволяющий описывать требуемую структуру XMLдокумента и синтаксические правила разбора исходного файла. 3.2.2 Утилита для работы с базами данных (Data Base Tool) Для хранения и редактирования данных в системе используются реляционные базы данных (Oracle, MySQL). Основное назначение утилиты – запись исходного “плоского” файла в таблицу базы данных и обратно, а также редактирование данных в таблицах. Для записи в таблицу исходный файл разбивается на отдельные поля с помощью соответствующего транслятора из Format Tool. После записи в таблицу доступ к данным может осуществляться посредством стандартных SQL-запросов.
110
Преобразование данных из “плоского” файла в таблицу и обратно взаимно однозначно. То есть, если не было произведено никакого редактирования таблицы, то полученный из нее “плоский” файл будет совпадать с исходным. Таким образом, утилита для работы с базами данных может служить “мостом” между двумя разными представлениями данных, используемыми в системе. Также существует процедура получения XMLдокумента из таблицы базы данных. 3.2.3 Поисковая часть системы (Retrieval System) Это основная часть информационной системы, предназначенная для поиска и организации доступа к биологической информации, хранимой в виде XMLдокументов, а также для администрирования системы в целом. В соответствии с этой функциональностью и категориями пользователей Retrieval System разделяется на административную и пользовательскую (поисковую) части. 3.2.4 Утилита для администрирования системы (Admin Tool) Основное назначение этого инструментального средства – администрирование внутренних данных системы для организации последующего поиска. Admin Tool работает с данными, представленными в виде банков, которые, в свою очередь, могут объединяться в семантически связанные группы (как правило, группа соответствует одному формату исходных данных). Каждый банк данных состоит из файлов, являющихся XML-документами и множества индексов, построенных на основе сбалансированного бинарного дерева. Admin Tool позволяет создавать и удалять банки данных, объединять их в группы, заполнять банки данных файлами, строить и уничтожать индексы. Для более гибкой и универсальной схемы работы с индексами используется механизм дополнительных имен – псевдонимов (aliases). Набор псевдонимов редактируется и поддерживается администратором системы. Будучи одним для всей системы, для всех банков данных механизм псевдонимов дает возможность использовать одно имя при спецификации поиска по разным банкам данных с использованием разных индексов. Особым видом индексов являются индексы по перекрестным ссылкам между банками данных. Множество косвенных ссылок представляет собой граф со
множеством связей. При поиске бывает полезным учитывать не все имеющиеся связи, а только некоторое подмножество. Возможности редактирования этого подмножества предоставляется Admin Tool. Для удобства организации поиска поддерживается множество словарей, хранящих именованные запросы. Admin Tool предоставляет средства редактирования этих словарей. 3.2.5 Утилита для поиска (Search Tool) Эта часть системы предназначена непосредственно для поиска и доступа к биологической информации. Основной способ поиска – это поиск по образцу в текстовых элементах документа. При задании образца можно строить регулярные выражения, используя символы ‘*’ (ноль или больше символов) и ‘?’ (ровно один символ). Например, ‘Verte*brat?’, ‘Primates’ или ‘*malia’. Для полей, содержащих имена авторов и даты, реализован специализированный поиск. Вместо одного регулярного выражения для авторов указываются отдельно образцы для поиска по фамилии и инициалам соответственно, а для дат – по дню, месяцу и году. Например, ‘name = Kitamura; initials = *;’. Также система поддерживает специализированный поиск по датам и числовым элементам. Для этих данных в спецификации запроса можно использовать операции сравнения. В каждом запросе указывается один или несколько банков данных, конкретный индекс, по которому будет производиться поиск, и образец для поиска. Несколько подзапросов могут объединяться в один запрос с помощью логических связок (and, or и not). Особой поисковой операцией является поиск по перекрестным ссылкам между банками данных. Для спецификации запросов разработан специальный язык. Результатом любого поиска является набор записей из некоторого множества банков данных, удовлетворяющих запросу. По умолчанию пользователю доступны только идентификаторы записей, по которым затем можно получить для просмотра их содержание. Помимо этого существует возможность указать при спецификации запроса имена тех полей, которые вместе с идентификаторами записей будут сразу доступны при просмотре результатов поиска. Также система позволяет уточнять запросы, строя новые запросы над результатами предыдущего поиска.
111
3.2.6 Пользовательские интерфейсы В BiomaxRS пользовательские интерфейсы строятся как клиентская часть CORBA-приложения, могут быть реализованы на произвольной платформе и быть удаленными по отношению к ядру системы. Интерфейсы предоставляют пользователям (локальным или удаленным) доступ к необходимым функциональным возможностям информационной системы. Для информационных систем характерно повышенное требование к качеству пользовательских интерфейсов. Развитие сетевых технологий и концепции клиент-сервер предоставляет богатые возможности для построения пользовательских интерфейсов, используя стандартные средства сети Internet и WWW-технологий. При разработке любого интерфейса, основанного на гипертекстовых технологиях, возникает вопрос о генерации web-сервером представляемых пользователю HTML-документов. В BiomaxRS используется архитектура webсервера, предполагающая логическое деление на несколько уровней: некоторый конкретный HTTP-сервер и модуль, обеспечивающий взаимодействие с ним, модуль обработки запросов, представляющий собой уровень бизнеслогики, модуль генерации HTMLдокументов и некоторый внешний архив, содержащий описание пользовательского интерфейса. Элементами этого архива являются содержательное описание для каждого конкретного HTML-документа и единое описание графического оформления для всех HTML-документов системы. Описание осуществляется на языке EH (Extended Hypertext – расширенный гипертекст), специально разработанном для решения проблемы генерации содержимого HTML-документов. Документ на языке EH представляет собой некоторый шаблон, в который подставляются динамические данные, полученные от модуля обработки запроса. Динамические данные при этом могут иметь сколь угодно сложную структуру. Языковые средства EH позволяют производить сложную обработку динамических данных при помощи операторов циклов и условных операторов. Макроопределения и макроподстановки дают широкие возможности для переиспользования кода, а также для разделения оформления и содержания документов. В рассматриваемой информационной системе web-сервер основан на
универсальном HTTP-сервере Apache. Основная часть web-сервера представляет собой FastCGI-приложение, взаимодействующее с ядром информационной системой посредством технологии CORBA. В соответствии с предложенной архитектурой, FastCGIприложение состоит из модуля поддержки FastCGI, модуля обработки запроса и модуля генерации HTML. Web-сервер предоставляет доступ к системе посредством так называемых сессий. В начале работы каждый пользователь осуществляет авторизацию, после чего web-сервер заводит для пользователя отдельную сессию. Состояние всех сессий инкапсулировано в модуле обработки запроса. Модуль обработки запроса фактически представляет собой некоторый автомат, управляемый HTTP-запросами. В ответ на каждый запрос модуль применяет указанную операцию к указанной сессии, меняя состояние последней. После выполнения операции, ее результаты используются для генерации и выдачи указанного документа. Поведение автомата определяется исключительно EHописаниями и может быть изменено в динамике без перезапуска web-сервера. После завершения выполнения запроса модулю генерации HTML передается указание на вывод документа из файла, содержащего определенный шаблон. Имя файла определяется модулем обработки запроса и передается в виде параметра. Модуль генерации HTML загружает указанный документ и осуществляет его вывод с использованием макроопределений языка EH, соответствующих текущей сессии. Помимо гипертекстового интерфейса система предоставляет пользователям интерфейс, обладающий той же функциональностью, но работающий в режиме командной строки.
4.Научные исследования и разработки 4.1. Методология разработки распределенных приложений на основе модели оболочки Создание унифицированной среды разработки и поддержки времени выполнения ориентировано на разработку распределенных приложений с высокими требованиями к эффективности, и, прежде всего, на приложения реального времени. В основе подхода к созданию такой среды лежат механизмы адаптации,
112
обеспечивающие гибкие возможности оптимизации взаимодействий удаленных объектов. На концептуальном уровне множество всех объектов распределенного глобального пространства представляется покрытым множеством специального вида подмножеств – оболочек. Каждая оболочка содержит некоторую совокупность семантически взаимосвязанных объектов. Любое взаимодействие двух объектов поддерживается прозрачным образом оболочками, содержащими эти объекты. Любой объект вызывает метод другого объекта независимо от их взаимного расположения (локального или удаленного), от свойств взаимодействующих оболочек (объектной модели, поддерживаемой конкретной оболочкой, организации мультидоступа к объектам оболочки, методов поддержки секретности внутри оболочки и т.п.) и от способов коммуникации между оболочками (может использоваться IIOP CORBA 2.0 [CORBA98] или любой другой специфический протокол). В жизни объекта различают две фазы: проектирования и выполнения. Оболочки поддерживают и организуют взаимное согласование объектов на обеих фазах. То есть, оболочки являются одновременно и средой проектирования объектов, и средой выполнения. Поскольку оболочки ответственны за поддержку согласованного прозрачного взаимодействия объектов, сами оболочки нуждаются в некоторой дисциплине согласования. В принципе, мы могли бы представить себе однородный мир оболочек, отвечающих некоторому одному стандарту организации взаимодействия между объектами, например, CORBA [CORBA98]. Мы, однако, хотели бы предложить более разнообразный и богатый мир оболочечных моделей, обладающих не только разными свойствами, но и разными свойствами описания этих свойств, т.е. метасвойствами. Согласование оболочек может происходить как на стадии проектирования объектов (статическое согласование оболочек), так и на стадии выполнения (адаптивное динамическое согласование). Для гибкого согласования оболочек естественно использовать технику метаобъектного контроля [KRB91]. Однако традиционно метаобъектный контроль используется либо на фазе проектирования, либо на фазе выполнения.
В первом случае [Chi96] мы получаем высоко эффективный, но монолитный код, который уже не может быть изменен во время выполнения некоторым систематическим образом. В процессе распределенной обработки данных зачастую возникают ситуации, требующие проведения существенных изменений схем согласования оболочек. Например, это требуется в случаях миграции объекта (объект может переместиться в оболочку, имеющую другие свойства) или изменения свойств самой оболочки (например, изменения требований секретности в оболочке-предприятии). При второй альтернативе платой за исключительную гибкость (неограниченная возможность динамической трансформации) управления вызовами методов объектов во время выполнения является потеря производительности, по крайней мере, в десятичный порядок [ZC95, ZC96], в результате использования интерпретации. Наш подход в использовании метаобъектного контроля [IZKN96, IDZ97] есть некоторый компромисс между двумя этими альтернативами. Его идея заключается в следующем. На стадии проектирования мы подготавливаем различные варианты возможного метаконтроля для организации взаимодействия объектов (возможно и его отсутствие). И тем самым получаем высоко эффективные варианты кода. На фазе же выполнения используется тот или иной вариант. Более того, текущий вариант во время выполнения может быть заменен другим (динамическое согласование оболочек). Подключение прикладного объекта к метаконтексту, состоящему из метаобъектов, осуществляется с помощью специального метаобъекта, названного нами интерфейсным объектом (ИО). В терминах модели “клиент-сервер”, некоторый клиентский объект может вызывать метод серверного объекта либо непосредственно, не подключаясь к метаконтексту, либо через соответствующий ИО, выполняющий роль посредника. Этот посредник осуществляет пред- и пост- вызовы метаобъектов. Отметим, что для того, чтобы подключение ИО было прозрачным для объектов приложений, в этих приложениях должен использоваться некоторый механизм позднего связывания объектов. Будучи средой обитания объектов, оболочка содержит набор ортогональных метасервисов (семантически связанные
113
коллекции метаобъектов). Предположение об ортогональности чрезвычайно важно и предоставляет следующие возможности: • естественным образом подключать прикладные объекты к различным функциональным элементам метаконтекста прозрачно для прикладных объектов; • развивать независимо различные функциональности, т.е. метасервисы; • добавлять новые метасервисы, т.е. проводить метанаращивание оболочек без изменения уже существующих метасервисов. Подчеркнем еще раз, что подключение к метаконтексту осуществляется прозрачно как для клиентских, так и для серверных объектов. Организация метаконтроля не затрагивает реализации приложений (клиента и сервера). В этом смысле можно говорить, что любой объект приложений рассматривается как “черный ящик”. В случае удаленных объектов происходит естественное расщепление ИО на ИО клиента и ИО сервера (аналогия пары “стаб – скелетон” в архитектуре CORBA). Причем метаконтроль, производимый в этих двух ИО, может быть частично или полностью независимым. Когда нет полной независимости, необходимое согласование клиентского и серверного ИО обеспечивается соответствующими оболочками, в которых эти ИО находятся.
Рис. 4. Схема организации метаконтроля На рисунке 4 приведена схема организации работы двух взаимодействующих объектов как через клиентский, так и через серверный ИО. Для проектирования используется набор из трех языков: языка реализации, языка спецификаций и языка описания метаобъектных связей. Поскольку мы хотим иметь возможность получать надежный, высоко эффективный код, язык реализации должен быть объектноориентированным языком со строгой типизацией. В качестве языка
спецификаций для описания типов объектов целесообразно использовать IDL. Такой выбор гарантирует совместимость с промышленным стандартом CORBA. Для описания различных вариантов подключения целевых объектов к метаконтексту, т.е. для описания наполнения интерфейсных объектов, предлагается некоторый язык шаблонов для пошаговой спецификации метаконтроля с рабочим названием – TL (Template Language). Итак, предлагаемый подход к созданию единой среды конструирования распределенных систем базируется на нескольких основных идеях: ортогональной декомпозиции системы, метаобъектном контроле с использованием развитой техники объектных посредников, согласовании распределенных компонентов – оболочек. 4.2. Надстройка над стандартным отображением из CORBA IDL в C++ В процессе разработки брокера объектных заявок C++ ISP ORB был обнаружен ряд существенных недостатков отображения из языка спецификаций интерфейсов IDL в язык реализации C++, затрудняющих работу программиста в рассматриваемой среде. Например, для работы с объектными ссылками для каждого интерфейса, скажем А, определенного в IDL-спецификации, стандартное отображение предусматривает два типа ссылок – A_ptr и A_var, совершенно различных по схеме работы с памятью. По сути, A_ptr является просто указателем, а A_var – специальный объект, имеющий конструктор и деструктор, владеющий памятью, на которую указывает. То есть, уничтожение объекта A_var обязательно влечет за собой и уничтожение памяти, на которую он ссылается. При этом значение переменной любого из этих типов может быть присвоено переменной другого типа, определено преобразование типа A_var в A_ptr. Во всех этих случаях дублирование памяти не производится. Не предусмотрено никаких средств контроля подобных манипуляций с данными этих типов. Это и служит весьма распространенным источником проблем при работе с объектными ссылками. Правила передачи параметров и результатов, предполагаемые стандартом, существенно зависят от свойств передаваемого типа и направления передачи параметра (IN, INOUT, OUT,
114
RESULT). Простыми их можно назвать только для примитивных типов данных. Для составных же типов правила манипулирования памятью для передаваемых параметров зависят от свойств конкретного типа (например, переменной или постоянной длины). Определенным недостатком можно считать требование стандарта, запрещающее передавать клиенту и серверу в качестве параметра или результата нулевой указатель. Даже если при выполнении метода сервера возникла исключительная ситуация, все OUT параметры и результаты должны быть чемто заполнены. Для каждого составного типа Т стандарт предполагает использование дополнительного типа Т_var. Объекты этого типа играют роль “умных” указателей, владеющих памятью, на которую ссылаются. Допустимые неявные приведения между объектами типов Т* и T_var, как и в случае с объектными ссылками, провоцируют некорректную работу с памятью. Безобидное присваивание строки вида CORBA::String_var var = “some string”; влечет попытку удаления статической памяти при уничтожении переменной var. Предлагаемый подход также основан на использовании специальных оболочекпосредников для данных составных типов. Но в отличие от посредников типа T_var, оболочки предполагают более последовательную и надежную работу с памятью. Пользователь может себе представлять оболочки как “умные” контейнеры, содержащие данные соответствующего составного типа. Основой концепции работы с памятью здесь является тезис о том, что память, содержащаяся в оболочках, никогда не доступна для управления пользователем. То есть оболочки сами создают память под данные и уничтожают ее. Пользователь же лишь может указать, откуда скопировать данные в эту память, может посмотреть ее содержимое и может изменять значения элементов составных данных, хранимых в оболочке. Все неявные операции работы с памятью (присваивания и инициализации) заключаются в глубоком копировании данных. Неявное приведение из типа T_var в тип T* запрещено, так как семантика такого преобразования не вполне ясна. Для присваивания из оболочки в переменную соответствующего базового
типа необходимо использовать тот или иной явный метод. Платя некоторой потерей эффективности, пользователь может использовать оболочки и не задумываться о правильности работы с памятью. При работе с ORB’ом пользователю предлагается проводить все необходимые манипуляции с данными только через подобных посредников. В частности, только с их помощью организуется передача параметров методов и получении результатов для составных типов.
Рис. 5. Предлагаемое отображение для типов параметров и результатов Сама схема передачи параметров с использованием оболочек становится предельно простой (рис. 5). При этом способ передачи параметров не зависит от свойств типа. Для повышения эффективности предусмотрен ряд явных операций, позволяющих оптимизировать работу с памятью там, где это действительно необходимо. Например, можно записать в оболочку указатель, не передавая при этом права на владение памятью. В этом случае уничтожение оболочки не повлечет за собой удаления памяти, которая может быть, например, статической. С помощью других явных операций пользователь может использовать для чтения память, управляемую оболочкой, без дополнительного копирования. Важной особенностью оболочек является то, что их не обязательно явным образом инициализировать. Изначально они уже содержат данные, заполненные по умолчанию: все элементы данных, имеющие конструктор, заполнены с помощью конструктора по умолчанию, остальные – просто обнулены. Это гарантирует, в частности, возможность возврата результатов (в том числе через INOUT и OUT параметры) методов без их явного заполнения. В отличие от объектов типа T_var, которые до явной инициализации содержат нулевой указатель, оболочки всегда находится в корректном состоянии. При первом обращении к оболочке, которой не было присвоено никакого значения, происходит инициализация данных по умолчанию в соответствии с внутренним типом.
115
В случае использования до явного заполнения значения оболочки, содержащей данные типа объединения (union), используется соглашение о том, что начальным значением дескриптора объединения является либо значение по умолчанию (default), указанное в IDL спецификации для этого типа, либо, если таковое умолчание не было определено, используется первое определенное в IDL спецификации значение дескриптора (схема, используемая при инициализации объединений в C++ – заполняется именно первое поле). В качестве данных объединение содержит данные того типа, который соответствует выбранному указанным образом дескриптору, и заполнены также по умолчанию, используемому для этого типа. В стандартном же отображении, до явного присваивания объединение находится в некорректном состоянии, и в принципе запрещено использовать дескриптор объединения без его явной предварительной инициализации. Для контроля состояния оболочки предусмотрен специальный метод is_nil (). Он возвращает истину, если оболочка так и не была проинициализирована явно, и ложь в противном случае. Предложенная концепция оболочекпосредников решает проблему повышения надежности программного обеспечения и упрощает программирование с использованием этого отображения. Важно отметить, что использование оболочек не является альтернативой стандартного отображения, а является его дополнением. То есть новый подход реализован в виде некоторой надстройки над произвольной системой управления объектами, удовлетворяющей стандарту CORBA 2.1. 4.3. Маршалинг данных в гетерогенных средах В процессе тестирования брокера объектных заявок C++ ISP ORB было замечено, что при передаче данных между машинами, объединенными локальной сетью, подавляющая часть времени тратится на преобразование данных в формат, пригодный для передачи по сети, и обратно. В результате исследований было предложено несколько подходов к оптимизации процедур преобразования данных (маршалинга). В распределенных неоднородных системах неизбежно возникает задача преобразования данных, связанного с использованием pазличных платформ и/или пеpедачей данных по сети. Процедура
пpеобpазования данных из одного фоpмата в дpугой получила название маpшалинга. Маршалинг включает линеаризацию сложных структур данных, учитывает порядок байтов, ту или иную cтратегию выравнивания (значения базовых типов выравниваются на границу кратную их размеру в байтах; выравнивание всех границ на максимально возможный размер данных). В распределенных технологиях фоpмат пpомежуточного, сетевого пpедставления данных также является частью стандаpта. Например, стандарт CORBA включает формат уровня представления данных Common Data Representation (CDR). В связи с увеличением быстpодействия совpеменных компьютерных сетей время маршалинга во многом стало определять скорость взаимодействия. Поэтому проблемы оптимизации форматов и построения эффективных протоколов передачи данных становятся ключевыми. Возможны различные подходы к повышению эффективности протоколов. Например, использование оптимальных по размеру данных и способу интерпретации схем кодирования. Ярким примером деятельности в этой направлении является ситуация с языком описания структурной информации Abstract Syntax Notation (ASN.1). Его использование для спецификаций протоколов передачи данных не получило широкого применения из-за недостаточно эффективной схемы кодирования Basic Encoding Rules (BER), изначально разработанной для ASN.1. Поэтому был предложен ряд альтернативных схем – Packed Encoding Rules (PER), Efficient Packed Encoding Rules (EPER), Lightweight Encoding Rules (LWER), более оптимальных как по размеру закодированной информации, так и по скорости кодирования/декодирования, что существенно увеличило популярность ASN.1. Другой подход связан с различными вариантами реализации самих процедур маршалинга: использование различных техник (компиляция, интерпретация), объединение атомарных операций на этапе компиляции протоколов, генерация процедур, оптимальных по размеру кода и времени выполнения в соответствии с результатами профилирования программы. Также рассматриваются варианты реализации эффективных базовых процедур маршалинга на аппаратном уровне. На сегодняшний день возможность корректного взаимодействия программных систем в неоднородных средах
116
определяется использованием формальных языков спецификаций для построения надежных и верифицируемых протоколов. Процедуры маршалинга получаются по спецификациям с помощью средств кодогенерации. Но традиционно наиболее критичный по времени исполнения код программируется вручную. Сегодня возникает задача автоматического порождения эффективных и надежных протоколов передачи данных. Помимо надежности и верифицируемости получаемого автоматически кода, использование формальных языков спецификаций и применение техники компиляции позволяет еще на стадии анализа синтаксического дерева спецификации осуществлять ряд предварительных вычислений. Например, для данных, имеющих фиксированную длину, может быть вычислен размер буфера, необходимый для их размещения. При этом учитывается структура типа и соответствующие правила выравнивания внутренних полей. Применяемая таким образом техника смешанных вычислений предоставляет дополнительные возможности оптимизации процедур маршаллинга. На примере реализации брокера С++ ISP ORB были рассмотрены различные подходы к реализации процедур маршалинга. Наиболее общим подходом к реализации процедур маpшалинга для составных типов является выбор между возможностями интерпретации и компиляции (в сочетании с inlineподстановками). И интерпретация, и компиляция имеют свои хорошо известные достоинства и недостатки. Интерпретируемый код компактен, но сама процедура интерпретации достаточно медленна. Выполнение скомпилированного кода намного быстрее, но при этом размер кода может существенно увеличиться. В контексте реализации брокера С++ ISP ORB интерпретация подразумевает процедуру рекурсивного обхода некоторой универсальной структуры (называемой TypeCode), которая описывает внутреннее строение составных данных. В случае компиляции для каждого составного типа компилятором порождаются типизированные процедуры маршалинга. Эксперименты с С++ ISP ORB показали, что время выполнения скомпилированных процедур маршалинга в 3-4 раза меньше времени, требуемого процедурой интерпретации (в зависимости от сложности типа). Использование скомпилированных процедур маршалинга
дает наибольший выигрыш по времени при работе с данными глубокой вложенности. При маршалинге таких данных интерпретатор превращается в достаточно длинную последовательность рекурсивных вызовов. В то же время скомпилированные процедуры маршалинга, с учетом использования inline-подстановок, позволяют практически избежать накладных расходов на дополнительные вызовы процедур. При этом размер объектного кода за счет применения типизированных процедур маршалинга увеличивается в среднем на 30%. Встречаются ситуации, когда использование определенной техники маршалинга неизбежно. Например, с помощью процедуры интерпретации можно “маршалировать” данные, типы которых не были известны в момент компиляции и, следовательно, для них просто не существует скомпилированных процедур маршалинга. В свою очередь, скомпилированный код более гибок по отношению к размещению данных в памяти. Если на некоторой платформе используются оптимизирующие компиляторы, то порядок полей структуры, зафиксированный в TypeCode, может не соответствовать реальному размещению данных и, следовательно, процедура интерпретации TypeCode не может быть использована. Для реализации С++ ISP ORB время выполнения было наиболее критичным параметром, поэтому предпочтение было отдано скомпилированным процедурам маршалинга. Интерпретирующая процедура сохранилась для использования только в отдельных случаях. Но принимая во внимание перечисленные достоинства и недостатки подходов, более гибкой представляется комбинированная технология маршалинга с учетом частоты использования типов [Hosh96]. По принципу "локальности" рабочего множества, большую часть времени выполнения приложения по сети передаются данные некоторого ограниченного множества типов. Для этих типов порождаются типизированные процедуры маршалинга, более эффективные по времени выполнения, но существенно увеличивающие размер кода. В целях уменьшения размера кода для маршалинга данных остальных типов используется менее эффективная, но более компактная процедура интерпретации. Таким образом достигается определенный баланс между размером кода и скоростью
117
выполнения. Инфоpмация об использовании типов может быть получена путем профилирования программ или с помощью статического анализа IDL спецификаций (дополнительный проход по абстрактному синтаксическому дереву и вычисление атрибутов – частоты использования). Дpугой способ оптимизации процедур маршалинга – объединение атомарных операций маршалинга для данных составных типов еще на этапе компиляции. Примитивы маршалинга включают вычисление границы выравнивания, вычисление размера памяти, необходимого для записи данных, выделение памяти и непосредственно запись самих данных. В общем случае последовательность таких действий выполняется для каждого примитивного типа, входящего в составной тип. Очевидно, что для данных имеющих, фиксированную длину, требуемый размер памяти может быть вычислен еще при построении типизированных процедур маршалига, на основе анализа абстрактного синтаксического дерева. А выделение памяти в буфере и на стороне сервера может быть осуществлено единой опеpацией. Если структура имеет определенную последовательность полей (например, поле типа short следует за полем типа long) можно исключить лишнюю проверку границы выравнивания. Компилятор протоколов, учитывающий перечисленные нюансы оптимизации, находится на стадии реализации. 4.4. Активные модели Создание распределенных параллельных систем на сегодняшний день остается сложной задачей, хотя предложено много различных подходов и решений. Объектноориентированное программирование дало новый импульс в исследованиях, посвященных этой теме. Понятие объекта и модель взаимодействия объектов, основанная на передаче сообщений (message passing), являются достаточно мощными и гибкими средствами для выражения различных видов вычислений. Многие объектные языки программирования и системы имеют параллельные и распределенные расширения, и почти каждое новое исследование в области распределенных систем основывается на объектном подходе. Как результат, сейчас создано и продолжает создаваться множество различных распределенных и параллельных объектных моделей. Например, языки программирования Ада-83 [ADA83] и Ада-
95 [ADA95], среда функционирования и создания программ КЛАСТОС [BIK], акторные языки [AGH86], языки программирования C++// [CBR] и Java// [CVAY], модель постоянно хранимых потоков управления (Persistent threads) [MS94], система объектно-ориентированного моделирования приложений реального времени Real-time Object-Oriented Modeling (ROOM) [SGW94], модель взаимодействующих последовательных процессов, предложенная Ч. Хоаром, Communicating Sequential Processes (CSP) [CHH89]. В процессе исследовательской работы был рассмотрен ряд моделей, предложена их классификация и на ее основе предложена метамодель, позволяющая с одной стороны предоставить программисту уже освоенные средства, заимствованные из предшествующих моделей, а с другой стороны освободить его от решения типичных проблем и по возможности защитить от ошибок программирования. Под активной моделью мы понимаем часть объектной модели, описывающую активности, соотношение их с традиционными объектами (в терминах конкретной объектной модели) и взаимодействие активностей между собой и, возможно, объектами. Понятие активности (процесс, задача, поток управления) – общая точка соприкосновения рассматриваемых моделей. Семантика активности различается от модели к модели. Также различаются и другие понятия активных моделей, каждое из которых можно рассматривать подробно и выделять на этом основании типы систем. Например, взаимодействие между объектами включает в себя соотношение между вызывающим и вызываемым объектом (один к одному, один к нескольким и так далее), способ их синхронизации (удаленный вызов процедуры, асинхронное взаимодействие и так далее). Эти и им подобные понятия положены в основу классификации. Классификация моделей не является самоцелью и служит основой для создания метамодели. Целью метамодели является описание некоторого класса моделей широко используемых систем (языков программирования, операционных систем, систем моделирования) и формирование базиса интероперабельности между приложениями, созданными в описанных моделях. Метамодель не ставит своей целью предоставить средства для описания моделей произвольных распределенных
118
параллельных систем. Исследуются в основном аспекты параллельного исполнения и взаимодействия объектов, а также связанные с ними вопросы синхронизации и конкурентного доступа. Рассматривается набор конкретных моделей (относительно которых можно заметить, что большинство из них применяются на практике) и иллюстрируется возможность выражения их понятий и примитивов через понятия и примитивы метамодели. Модель предлагает общее понятие активного объекта. Во время жизни объекта в распределенной параллельной системе можно выделить следующие важные для него этапы: • создание объекта и создание соответствующей ему активности; • уничтожение объекта и уничтожение соответствующей активности; • взаимодействие объектов, которое в свою очередь состоит из более мелких шагов (получение объектной ссылки, формирование сообщения, его маршалинг и т.д.). Передача сообщений в распределенной системе должна поддерживаться соответствующей инфраструктурой. Примером может служить технология CORBA и соответствующее программное обеспечение реализующее и поддерживающее ее. Объект в метамодели состоит из следующих составных частей: 1. Генератор активностей – предназначен для создания активностей в разные моменты жизни объекта (является фабрикой объектов-активностей); 2. Объект-активность (в одном объекте их может быть один или несколько). Активности могут быть созданы статически или динамически; 3. Коммуникатор – обеспечивает взаимодействие объектов путем транспортировки сообщений от одного другому. Является посредником между взаимодействующими объектами. Семантика операций этого объекта влияет на способ общения между объектами. Может обеспечивать синхронные или асинхронные операции передачи сообщений; 4. Диспетчер – запуск активности на выполнение или активизация сообщений – принимаемых или посылаемых (в объекте может быть один или несколько диспетчеров).
5.
6.
Удобно выделять два вида диспетчеров – для сообщений-запросов и сообщений-ответов. Диспетчеры могут реализовывать разные политики обслуживания соответствующих очередей. Политики (реализации разных схем) синхронизации могут быть оформлены в виде отдельных объектов; Очереди запросов и ответов – поддерживают списки сообщений и служат для буферизации запросов и ответов; Сообщения – динамически порождаемые объекты, инкапсулирующие запросы или ответы.
Предлагаемая схема предоставляет интерфейсы, обобщающие все рассмотренные модели. Она позволяет реализовывать указанные интерфейсы в соответствии с данной моделью. Предполагается библиотечная реализация системы на основе предлагаемой схемы, а также соответствующих средств поддержки. 4.5 Адаптация унаследованных систем в CORBA-среду Технология построения распределенных систем подразумевает их принципиальную открытость. Принципы отделения интерфейсов от реализаций, спецификации интерфейсов с помощью средств, независимых от конкретных языков реализаций, предполагают потенциальную возможность расширения этих систем как с помощью новых технологий, так и за счет адаптации унаследованного кода (legacy system). Прямой порядок разработки распределенной системы подразумевает следующую последовательность действий. Вначале интерфейс компонента специфицируется на независимом от реализаций языке определений. В архитектуре CORBA в качестве такого средства используется язык определения интерфейсов IDL. Далее по IDLспецификации средствами стандартных трансляторов порождаются модули, отображающие типы и структуры данных, и реализующие необходимый библиотечный код (например, процедуры маршалинга). И уже после этого, с использованием полученного по IDL-спецификации кода, пишется реализация компоненты. Для унаследованных систем реализация уже существует. Поэтому при модернизации унаследованной системы
119
самое важное – это суметь обеспечить взаимодействие ее объектной модели с моделью расширяющих объектов. В случае использования технологии CORBA модернизация системы включает следующие шаги. Во-первых, необходимо выделить ту часть системы, которую желательно сделать “открытой”. Во-вторых, тем или иным способом создать необходимые IDL-спецификации. И, наконец, в соответствии с прямым порядком разработки CORBA-приложений, реализовать полученные интерфейсы, опираясь на код существующей системы. Первый этап является наиболее творческим и под силу только разработчику. Получение же IDLспецификаций и кода посредников по имеющимся реализациям до определенной степени может быть автоматизировано. При получении IDL-спецификации возникает необходимость в “обратном” отображении из языка реализации в IDL. Как пpавило, модели и уровни абстракции языков реализации и IDL сильно отличаются. И как следствие, “обратное” отобpажение становится неоднозначным, и тpебует дополнительные инструкции по уточнению. Обратим внимание на тот факт, что потом по IDL-спецификации будет получен код на языке реализации уже в соответствии с “прямым” отображением. И таким образом неоднозначности отображения необходимо уточнять дважды. При разработке отображения из IDL в Protel-2 особое внимание было уделено исследованию проблем адаптации унаследованного кода в CORBA-среду. Было разработано “расширенное” отображение и реализован соответствующий компилятор, позволяющие по “расширенным” IDLспецификациям генерировать код, учитывающий особенности существующей системы. Язык IDL имеет встроенное средство для указания системно-зависимой информации компилятору – прагмы. В директивах pragma программист мог бы ссылаться на определения существующих в унаследованной системе типов, производить замену имен, использовать другие, уже скомпилированные IDLспецификации. Прагмы имеют смысл только для того компилятора, который умеет их интерпретировать. Стандартный компилятор с IDL просто игнорирует неизвестные ему прагмы. Для возможности использования существующего в унаследованной системе
кода были введены следующие классы прагм. • прагмы, предназначенные для включения текста на IDL или Protel-2 в IDL спецификацию или в порождаемые Protel-2 модули соответственно. Прагмы этого класса называются includeProtel, includes, inline, useProtel, uses; • прагмы, позволяющие изменять имена, генерируемые IDL компилятором по умолчанию: prefix, replaceid, filename; • прагмы, указывающие, что IDL спецификация для данного интерфейса будет использоваться только как клиентская или только как серверная: noclient, noserver; • наконец, прагмы, дающие возможность подменить порождаемый IDL компилятором тип, класс или атрибут класса на существующие (например, в унаследованной системе) объявления: maptype, mapinterface, mapattribute. Наиболее важным с точки зрения использования написанного кода является последний класс прагм. Вставленные в IDLспецификацию, они заставляют IDL компилятор не генерировать тип, класс или атрибут по умолчанию, а использовать вместо него указанный Protel-2 тип, класс или атрибут соответственно. Приведенные выше классы прагм предназначены для конкретного языка программирования – Protel-2, однако, аналогичным образом можно было бы расширить IDL компилятор с любого другого объектно-ориентированного языка. Итак, хотя технология CORBA рассчитана на создание новых объектноориентированных приложений, она может быть успешно использована и для распределения существующих объектных систем.
5. Заключение Возрастающая популярность распределенных систем подтверждает актуальность исследований в области распределенной обработки. Объектноориентированный подход, используемый как базовая модель во многих распределенных технологиях, остается одним их самых перспективных направлений в области разработки сложных распределенных приложений. Исследования подтвердили необходимость создания единой среды разработки и функционирования для распределенных систем. Такая среда
120
должна обеспечивать возможность расширения функциональности приложений путем “прозрачного” подключения системных сервисов, а также возможность согласования распределенных контекстов, в которых существуют прикладные объекты. Используя наработки в области повышения надежности и эффективности распределенного программирования, такая унифицированная среда может существенно упростить работу по созданию больших распределенных программных комплексов. В процессе работы была предложена модель оболочки, обеспечивающая прозрачное подключение сервисов и согласование распределенных контекстов на основе эффективной реализации метаобъектных протоколов. Часть проектов группы, реализованных в контексте исследований проблем распределенных вычислений, нашла конкретное практическое применение. В частности, брокер объектных заявок С++ ISP ORB свободно доступен в сети Internet, и судя по откликам, имеет определенную популярность. В рамках группы этот же брокер был использован для другого проекта, связанного с разработкой информационной системы для биологических банков данных, Biomax Retrieval System. Литература [CORBA97] Object Management Group. The Common Object Request Broker: Architecture and Specification, Revision 2.1, September 1997. [CORBA98] Object Management Group. The Common Object Request Broker: Architecture and Specification, Revision 2.2, February 1998. [COSS97] Object Management Group. CORBA Services: Common Object Services Specification, Revised Edition, July 1997. [BZKSh95] Д.О. Брюхов, В.И. Задорожный, Л.А. Калиниченко, М.Ю.Курошев, С.С. Шумилов, Интероперабельные информационные системы: архитектуры и технологии, Системы управления базами данных, N 4, 1995. [KK96] Л.А. Калиниченко, М.Р.Когаловский, Интероперабельность брокеров в стандарте CORBA 2.0, Системы управления базами данных, N 3,1996. [FDM94] Ira R. Forman, Scott Danforth, Hari Madduri. Composition of Before/After Metaclasses in SOM. OOPSLA 94- 10/94 Portland, Oregon USA [GC96] B.Gowing, V.Cahill. Metaobject protocols for C++: the Iguana approach. Proceedings of Reflection 96 Conference. 1996. [Chi96] Shigeru Chiba. OpenC++ Programmer's Guide for Version 2. Technical Report SPL-96-024, Xerox PARC, 1996. (http://www-masuda.is.s.utokyo.ac.jp/openc++.html) [IDZ97] В.П. Иванников, К.В. Дышлевой, В.И. Задорожный. Спецификация метанаращиваний
для эффективного метаобъектного контроля. Программирование, N 4, 1997. [IZKN96] Ivannikov V., Zadorozhny V., Kossmann R., Novikov B. Efficient Metaobject Control Using Mediators. 2nd Int.A.Ershov’s Conf., Novosibirsk, 1996 [KRB91] Kiczales G., des Rivieres J., Bobrow D. The Art of the Metaobject Protocol. MIT Press, 1991. [MMAY95] Masuhara H., Matsuoka S., Asai K., Yonezava A. Compiling Away the Meta-Level in Object-Oriented Concurrent Reflective Languages Using Partial Evaluation. OOPSLA'95. 1995. p. 300-315. [ZC95] Chris Zimmermann and Vinny Cahill. How to Structure Your Regional Meta: A New Approach to Organizing the Metalevel. In Proceedings of META '95, a workshop held at the European Conference of Object-Oriented Programming, 1995. [ZC96] Chris Zimmermann and Vinny Cahill. It's Your Choice – On the Design and Implementation of a Flexible Metalevel Architecture. Proceedings of the International Conference on Configurable Distributed Systems, IEEE, Annapolis, Maryland, May, 1996. (ftp://ftp.dsg.cs.tcd.ie/pub/doc/dsg100.ps.gz) [IVDKM97] В.П. Иванников, А.Н. Винокуров, К.В. Дышлевой, В.Е. Каменский, А.В. Климов, С.Г. Манжелей, В.А. Омельченко, Л.Б. Соловская. Методология разработки распределенных приложений на основе модели оболочки. Вопросы кибернетики, N 3, 1997. [KMS97] В.Е. Каменский, А.В. Климов, С.Г. Манжелей, Л.Б. Соловская. Применение стандарта CORBA для унаследованных систем. Вопросы кибернетики, N 3, 1997. [DKS97] К.В. Дышлевой, В.Е. Каменский, Л.Б. Соловская. Маршалинг данных в распределенных системах: сравнение двух подходов. Вопросы кибернетики, N 3, 1997. [Hosh96] Philipp Hoschka. Automating Performance Optimisation by Heuristic Analysis of A Formal Specification. IFIP TC 6/6.1 International Conference on Formal Description Techniques IX (Teory, application and tools), 1996. [Dysh97] К.В. Дышлевой. IDL C++ меппинг. CORBA и возможная альтернатива. Вопросы кибернетики, N 3, 1997. [XML99] Extensible Markup Language (XML) 1.0. W3C Recommendation, February1998. (http://www.w3.org/TR/REC-xml/.) [AGH86] G. Agha, An Overview of Actor Languages, ACM SIGPLAN Notices, v. 21(10), October 1986. [MS94] F. Matthes, and J.W. Schmidt, Persistent Threads, In Proceedings of the Twentieth International Conference on Very Large Data Bases, VLDB, Santiago, Chile, September 1994. [BIK] Кузнецов С.Д., В.П.Иванников, И.Б.Бурдонов, А.С.Косачев, Г.В.Копытов. Принципы организации КЛОС - кластерной операционной системы. Программирование, N 6, 1990 [SGW94] B. Selic, G. Gullekson, P.T. Ward, RealTime Object-Oriented Modeling, John Wiley and Sons, 1994 (ROOM).
121
[CHH89] Ч. Хоар. Взаимодействующие последовательные процессы. Москва, 1989 (CSP). [CBR] D. Caromel, F. Belloncle, and Y. Roudier, The C++// Language. [CVAY] D. Caromel, and J. Vayssiere, A Java Framework for Seamless Sequential, Multithreaded, and Distributed Programming (Java//). [ADA83] Н. Перминов. Ада-83, Москва, 1990. [ADA95] Ada Reference Manual, Language and Standard Libraries, Version 6.0, ISO/IEC 8652:1995(E), December 1994. [Jas99] Jason W. Pegg. An introduction to Active Server Pages. (http://www.auroradevelopment.com/OnlineTrainin g/Introduction.htm.)
Объектно-ориентированная методология разработки интегрированных приложений моделирования и визуализации * Семенов В.А., Крылов П.Б., Морозов С.В., Роминов М.Г., Тарлапан О.А.
Аннотация В статье описывается объектноориентированная методология построения интегрированных приложений моделирования и визуализации в различных предметных областях на единой концептуальной, инструментальной и программной основе. Разрабатываемые приложения имеют общую открытую архитектуру, которая включает объектноориентированное ядро, инвариантное по отношению к различным областям и проблемам, унифицированный графический интерфейс пользователя и специализированные прикладные библиотеки классов. Объектноориентированное ядро поддерживает представление итоговой графической сцены в виде композиции связанных типизированных данных и алгоритмов и реализует общие механизмы составления сценариев работы приложений и их интерпретации. Функциональность приложений определяется главным образом полнотой подключенных прикладных библиотек и семантикой их классов. Достоинства предложенной методологии демонстрируются примерами разработки на ее основе системы научной визуализации общего назначения и специализированных приложений для изучения ряда актуальных физических проблем.
1. Введение В настоящее время компьютерные средства математического моделирования и визуализации научных расчетов получили широкое распространение и составляют неотъемлемую часть современных систем автоматизированного моделирования и проектирования (CAD/CAM/CAE). Разработка таких систем, сочетающих *
широкую предметную функциональность с развитыми графическими интерактивными вычислительными средствами, обычно требует чрезвычайно высоких затрат и сопряжена с решением целого круга проблем, включающего архитектурное проектирование, интеграцию функционально разнородных компонентов, организацию дружественного пользовательского интерфейса, обеспечение открытости, переносимости, эффективное использование на параллельных вычислительных системах. Разнообразие предметных областей науки и техники, в которых использование систем моделирования и визуализации является необходимым в силу невозможности или неэффективности проведения натурных экспериментов, а также высокая трудоемкость создания специализированных систем, в том числе и для проведения разнообразных междисциплинарных исследований, обуславливают необходимость выработки общей методологии их построения. В этом случае проблема создания новых программных систем переводится в плоскость активного использования уже имеющихся программных компонентов и их возможной адаптации к новым задачам. Поскольку, вырабатывая методологию, претендующую на существенную предметную общность, мы не можем конкретизировать семантику задач и назначение разрабатываемых программных компонентов, то будем исходить из следующих общих принципов построения приложений: • наличие унифицированного программного ядра, инвариантного по отношению к различным предметным областям, прикладным задачам моделирования и визуализации, применяемым аппаратным платформам;
Работа выполняется в рамках научно-исследовательских проектов «Объектноориентированная методология научной визуализации» (грант РФФИ 98–01–00321) и «Визуализация сложных физических явлений и математических объектов в виртуальной среде» (грант ИНТАС 96–0778)
123 • модульная организация или, другими словами, возможность построения конкретной прикладной системы из отдельного набора модулей, семантика которых соответствует сущностям рассматриваемой предметной области, способам их представления, программной реализации и, в конечном счете, определяет функциональность всей системы; • обеспечение гибкой дисциплины связывания экземпляров модулей с целью составления и применения различных сценариев конструирования функционирования сложных и композиционных сцен; • обеспечение механизмов обобщенной реализации модулей, при которой включаемые в систему новые модули могут взаимодействовать с имеющимися без строгой конкретизации контекста использования, а создание новых модулей может осуществляться на основе разработанных ранее; • программная реализация модулей на основе современных информационных, графических, коммуникационных стандартов, с использованием, в частности, стандарта представления геометрии (STEP) [1], языка описания сцен виртуальной реальности (VRML) [2], графической библиотеки растеризации изображений (OpenGL) [3], интерфейса распределенных приложений (MPI) [4]. Использование объектноориентированного подхода для построения прикладных программных систем в соответствии с вышеперечисленными принципами имеет ключевое значение, поскольку предусматриваемые им механизмы инкапсуляции, наследования и полиморфизма могут быть конструктивно применены как при реализации унифицированного ядра, так и при разработке прикладных библиотек классов [5, 6]. Настоящая работа преследует цель представить объектно-ориентированную методологию создания интегрированных приложений математического моделирования и научной визуализации, опирающуюся на оригинальную открытую модульную архитектуру. В разделе 2 проводится объектный анализ и описывается ядро приложений. Раздел 3 посвящен некоторым аспектам унифицированной разработки
интегрированных приложений с использованием данного ядра. В разделе 4 рассматривается система визуализации общего назначения OpenMV, построенная на основе предложенной методологии и разработанных программных средств и компонентов и иллюстрирующая их преимущества. В разделе 5 обсуждаются возможности специализации системы OpenMV для изучения сложных физических проблем.
2. Объектноориентированное ядро для моделирования и визуализации Будем рассматривать итоговую графическую сцену приложения как композицию связанных типизированных данных, участвующих во всех процессах данного приложения, включая моделирование, визуализацию и растеризацию, а также алгоритмов, создающих, преобразующих, удаляющих эти данные и реализующих упомянутые выше процессы. Будем различать пассивные объекты-данные, которые контролируют только собственное поведение, и активные объекты-алгоритмы, которые могут управлять поведением других объектов в результате рассылки им сообщений в классическом объектноориентированном стиле. Создание итоговой сцены подразумевает определение экземпляров классов данных и алгоритмов, установление связей между ними, составление сценария из отдельных объектов данных и алгоритмов и его интерпретации. Подобный подход, основанный на подразделении объектов на активные и пассивные, отражает основную идею методологии Бэйлина, известную как объектно-ориентированная спецификация требований [7], и успешно зарекомендовал себя при создании приложений вычислительной математики [6]. Рассмотрим более подробно объектноориентированное ядро для моделирования и визуализации. Под ядром понимается система абстрактных и конкретных классов, выражающих ключевые сущности рассматриваемой предметной области, реализующие базовые методы манипулирования ими и служащих конструктивной основой для построения широкого круга приложений с использованием принципов объектноориентированного программирования.
124 Базовым абстрактным классом ядра является класс Object, который выражает сущность произвольных данных и алгоритмов, участвующих в моделировании и визуализации. Объекты могут вводиться, конструироваться, связываться друг с другом, преобразовываться, запоминаться, визуализироваться, копироваться и уничтожаться в ходе работы приложения. Для единообразного манипулирования различными типами объектов и обеспечения функциональности ядра класс Object инкапсулирует идентификатор, номер версии и свое логическое местоположение в сцене (будет рассмотрено позже). Этими атрибутами обладают все объекты сцены, классы которых являются производными от Object. Помимо общих атрибутов каждый конкретный объект obj ∈ Object имеет свой собственный набор атрибутов, определяющий его внутреннее состояние и поведение, а также набор типизированных соединений. Соединения являются внешними портами объектов, посредством которых они могут быть связаны с другими подобными объектами. Тип конкретного соединения Link ⊆ Object определяет потенциальную возможность связи данного объекта с любым другим объектом lobj ∈ LinkObject, тип которого удовлетворяет типу соединения или, другими словами, является его подтипом LinkObject ⊆ Link. Наличие связей в сцене характеризует функциональную зависимость ее объектов и, следовательно, необходимость их совместного рассмотрения и анализа. Каждая установленная связь определяет отношения использования главным объектом других вспомогательных объектов, с которыми он связан. Будем различать одиночные и множественные связи. Одиночная связь определяет отношение использования между парой объектов, рассматриваемых как основной и вспомогательный. Множественная связь используется в тех случаях, когда основной объект находится во взаимодействии с подмножеством однотипных вспомогательных объектов через одно соединение lobj_i ∈ LinkObject_i ⊆ Link, i = 1, .., n. Число объектов n, объединенных множественной связью, является произвольным и зависит только от конкретного сценария, реализуемого в приложении. Для различия способов, с помощью которых объекты взаимодействуют между собой, все соединения и соответствующие
им связи подразделяются на входные, выходные и смешанные. Участвуя в связях, основной объект использует данные и методы вспомогательных объектов и, следовательно, может изменять состояния связанных с ним объектов. Предполагается, что основной объект способен изменять состояния вспомогательных объектов через выходные и смешанные связи, и неспособен влиять на состояние входных объектов. Основной объект зависит только от входных и смешанных объектов и не зависит от выходных объектов. Основной и вспомогательные объекты, включенные в смешанную связь, являются взаимозависимыми. Таким образом, могут быть установлены описанные отношения зависимости, основанные на классификации соединений взаимодействующих объектов. Инкапсулируя описанные выше свойства, класс Object определяет следующие группы методов, общие для всех его конкретных экземпляров: • создание (конструирование, уничтожение, копирование, чтение из файла, вывод в файл), • идентификация (идентификация объекта, его класса, базового класса, версии, верификация принадлежности к заданному типу), • взаимосвязывание (получение количества соединений, их классов и типов, связывание объектов), • получение информации о сцене (получение параметров сцены, логическое упорядочивание объектов в сцене). Основными понятиями ядра являются также объекты-данные dat ∈ Data ⊂ Object и объекты-алгоритмы alg ∈ Algorithm ⊂ Object. Абстрактные классы Data, Algorithm являются производными от Object и наследуют его свойства и поведение. Класс Data выражает сущность разнообразных научных данных, возникающих в приложениях моделирования и визуализации. Объектыданные являются пассивными объектами, контролирующими только собственное поведение, и поэтому могут иметь только входы. Класс Algorithm представляет различные алгоритмы, преобразования, операции и вспомогательные утилиты, реализующие все процессы в приложениях моделирования и визуализации. Алгоритмы являются активными объектами, контролирующими не только собственное поведение, но и поведение связанных с
125 ними вспомогательных объектов (не обязательно данных). Алгоритмы могут не иметь входов, но обязательно имеют выходные и/или смешанные соединения. Отличительная особенность алгоритмов заключается в возможности их активизации, которая реализуется при наступлении соответствующих событий в сцене. В этом случае сцена активизирует соответствующий метод выполнения алгоритма. Предполагается, что к моменту инициации все связи алгоритмов были установлены. В противном случае алгоритм не активизируется и рассматривается как объект-данное. При вызове метода запуска алгоритм рассылает сообщения связанным с ним объектам для получения информации о состоянии входных и смешанных объектов, выполнения необходимых операций над ними, а также для обновления состояния смешанных и создания выходных объектов.
Рис. 1. Иерархия классов и схема связывания и взаимодействия объектов
Рис. 2. Диаграммы классов и объектов в нотации Буча На рис. 1 представлен пример взаимодействия объектов. Данный пример иллюстрирует, каким образом данные и алгоритмы могут связываться и взаимодействовать через типизированные соединения. Иерархия классов определяет отношения наследования между классами данных и алгоритмов. Диаграмма сцены полностью определяет схему связывания и характер взаимодействия объектов. В диаграмме экземпляры данных и алгоритмов показаны, соответственно, как овалы и прямоугольники. Соединения
объектов промаркированы точками. Связи между объектами показаны стрелками. Подобная схема может быть представлена в терминах объектно-ориентированной методологии с использованием нотации Буча [8]. Для иллюстративности на рисунке 2 представлены диаграммы классов и объектов в нотации Буча для рассмотренного примера. Согласно диаграмме сцены данные dat1, dat2, dat3 связаны с алгоритмом alg через входные соединения. Множественное соединение link1 типа Data1 обеспечивает одновременную связь с dat1, dat2, удовлетворяющими его типу. Единственный объект dat3 связан через простое соединение link2 типа Data3. Аналогичным образом объекты dat4, dat5 связываются через смешанное соединение link3 и выходное соединение link4. После активизации алгоритм alg обменивается сообщениями с dat1, dat2, dat3, dat4, приводя к конструированию выходного объекта dat5 и обновлению dat4. Отметим, что принятый способ направления стрелок соответствует потокам данных в сценарии. Это обстоятельство выявляет схожесть с традиционной диаграммой потока данных, широко используемой в системах визуализации и анимации. Однако рассматриваемая диаграмма сценария выражает более общую парадигму "сущности-связи", которая, на наш взгляд, является более предпочтительной вследствие возможностей задания более сложных типов взаимодействия объектов. Задача моделирования и визуализации аттрактора, обсуждаемая ниже, дает пример взаимодействия объектов, которое не может быть представлено парадигмой потоков данных, но может быть специфицировано непосредственно в терминах нашего подхода. Наконец, класс Scene является контейнерным классом, поддерживающим упорядоченное представление (композицию) всех объектов данных и алгоритмов, включенных в сцену, и обеспечивающим широкую функциональность, необходимую для разрабатываемых приложений. Конструирование результирующей сцены осуществляется в результате непосредственного манипулирования ее объектами и активизации конвейера, составленного из ее отдельных алгоритмов. Алгоритмы конвейера сцены предварительно упорядочиваются и затем активизируются для решения частных задач
126 моделирования и визуализации. В ходе выполнения алгоритмов объекты сцены взаимодействуют друг с другом, что приводит к созданию новых объектов и обновлению уже существующих. Экземпляры класса Scene используются для представления сцен как композиций данных, а также для спецификации и интерпретации сложных сценариев моделирования и визуализации. Необходимость включения в сцену и алгоритмов связана с данных, и итеративным характером создания итоговой картины, в ходе которого последовательно корректируются свойства данных, уточняется состав и последовательность применяемых методик моделирования и визуализации, корректируются их параметры, устанавливается подходящая камера вида. Перечисленные действия близко связаны друг с другом и обычно требуются для воспроизведения изучаемого явления более адекватным и выразительным способом. Имея описанное представление сцены, можно модифицировать его вплоть до получения желаемого изображения. То же самое представление можно использовать для динамического моделирования и анимации полученных результатов. Эта возможность реализуема, поскольку однажды созданный сценарий может снова и снова использоваться для семантически эквивалентных наборов данных, сгенерированных приложением, а также введенных из файла или полученных от других процессов. Функциональность класса Scene обеспечивается абстракциями данных и алгоритмов, специфичных для разрабатываемых частных приложений. Данный класс определяет следующие группы методов: • создание (регистрация класса объекта, создание объекта данного класса, обновление версии объекта, копирование, удаление); • идентификация (получение объекта по его идентификатору, выбор объектов, принадлежащих заданному типу); • взаимосвязывание (связывание объекта с заданными вспомогательными объектами, автоматическое связывание объектов); • интерпретация сценария (получение физического и реального времени, номера итерации; планирование сценария (ранжирование сцены, упорядочивание ее объектов), анализ
латентных объектов, запуск отдельных алгоритмов и сценария в целом); • обработка событий приложения. Обсудим некоторые особенности манипулирования всей сценой и интерпретации соответствующего ей сценария. Для упрощения процедуры связывания обеспечивается специальный механизм автоматического связывания объектов. Данный механизм основан на анализе типов, выполняемом для всех объектов сцены, и включении подходящих объектов в связи, помеченные как автоматические. Все приемлемые объекты включатся в множественные связи. Только первые из выбранных объектов включаются в одиночные связи. Подобный механизм оказывается чрезвычайно полезным в тех случаях, когда тип объекта предопределяет некоторые семантические действия, которые следует выполнить автоматически. Например, является удобным отрисовать геометрические объекты автоматически сразу после их конструирования и включения в сцену. В этом случае процедура отрисовки всей сцены может быть реализована как алгоритм с множественным входным соединением типа GeometryData ⊂ Data. Всякий раз, когда конструируется новый геометрический объект, он связывается с данным алгоритмом и может автоматически отрисовываться без какихлибо дополнительных усилий. Определяя сценарий, пользователь располагает алгоритмы в той логической последовательности, в которой сцена должна их выполнять. Поскольку для больших сценариев это может вызвать затруднения, сцена позволяет упорядочивать алгоритмы автоматически. Так как классификация соединений объектов соответствует отношениям зависимости между ними, сцена способна анализировать связи между объектами для определения характера их зависимости и упорядочивания их в требуемом логическом порядке. Методы упорядочивания, предоставляемые классом Scene, основаны на ранжировании сцены. Ранжирование преследует цель присвоить каждому объекту пару целых чисел (ранг и индекс), указывающих его местоположение сценария. Подобные в диаграмме диаграммы показывают объекты сцены как геометрические примитивы, соединенные стрелками, и часто используются в системах визуализации и анимации как
127 эффективные средства для графического представления сценариев и их визуального программирования. Ранжирование устанавливает некоторый логический порядок следования объектов в сцене, при котором объекты с меньшим рангом не зависят от состояния объектов с большим или равным рангом, и, наоборот, объекты с большим рангом зависят только от состояния объектов с меньшим рангом. просто Процедура ранжирования формализуется и осуществляется путем последовательного приписывания рангов объектам в результате итеративного просмотра всей сцены. Нулевой ранг приписывается объектам, которые не имеют входных связей и не принимают участия в выходных связях других объектов. Для любого другого объекта ранг определяется как максимальный из рангов его входных объектов и объектов, связанных с ним через выходные соединения, плюс один при условии, что его собственные выходные объекты имеют неопределенный ранг. Смешанные связи последовательно рассматриваются как входные и выходные. Если ранг не может быть присвоен таким способом, и в сцене существуют объекты с неопределенным статусом, то это означает наличие как минимум одного цикла, и результат может оказаться ранжирования неоднозначным. В таких случаях ранг может быть присвоен первому объекту из оставшихся в соответствии с правилами, формализованными выше. Пользователь может влиять на способ, которым будут отранжированы объекты в обнаруженных циклах, предварительно упорядочив их. После окончания ранжирования объекты, имеющие один и тот же ранг, индексируются для определения их позиции в диаграмме сценария. Способность сцены ранжировать и упорядочивать объекты является очень важной для корректной интерпретации сценария, поскольку алгоритмы должны активизироваться в логическом порядке, приводя к передаче данных через алгоритмический конвейер и получению итоговой картины. Если данный порядок был нарушен, то возможно появление различных типов ошибок, связанных с попытками активизировать алгоритмы без наличия на их входах подготовленных данных. Если сценарий выполняется повторно, то на некоторых итерациях могут существовать латентные объекты.
Латентными объектами называются такие, состояние которых не изменяется на текущей итерации. Если входные объекты алгоритма не изменились на текущей итерации сценария, активизация этого алгоритма не вызовет изменений выходных объектов и, следовательно, не имеет смысла. Анализ латентности позволяет исключать избыточные события активизации латентных алгоритмов и, таким образом, повысить эффективность интерпретации сценария в целом. Сцена осуществляет анализ латентности путем сравнения версий входных объектов с их версиями, сохраненными на предыдущей итерации. Анализ латентности должен выполняться при интерпретации сценария. Наконец, класс Scene предоставляет метод для обработки типовых событий приложения. Такие события диспетчеризуются и напрямую рассылаются соответствующим методам сцены.
3. Разработка интегрированных приложений с использованием объектноориентированного ядра Рассмотренное выше объектноориентированное ядро обладает, на наш взгляд, достаточной общностью и гибкостью для его использования при создании разнообразных приложений моделирования и визуализации на единой концептуальной, методологической, инструментальной и программной основе. В самом деле, при применении ядра не требуется модифицировать его всякий раз для приспособления к частной задаче, семантике специфических объектов, их отношениям и возможным деталям программной реализации. Лежащие в его основе механизмы связывания и взаимодействия объектов позволяют составлять и интерпретировать сложные сценарии, возникающие в реальных задачах, без какого-либо уточнения семантики конкретных объектов приложения. Следовательно, в большинстве случаев создание приложения сводится к разработке прикладной библиотеки классов для представления используемых научных данных и для реализации методов моделирования и визуализации, специфичных для конкретной предметной области, а также к реализации графического интерфейса пользователя. Принимая во внимание преимущества объектноориентированного программирования,
128 реализацию прикладных библиотек классов данных и алгоритмов можно значительно упростить за счет неформального использования принципов инкапсуляции, наследования и полиморфизма. Обсудим самые общие вопросы создания приложений. При использовании рассмотренного объектноориентированного ядра разработка приложения сводится к проведению объектного анализа рассматриваемой предметной области, выделению специфичных для нее научных данных и алгоритмов, а также к проектированию и реализации специализированной библиотеки классов для представления этих объектов и манипулирования ими. Разработка конкретного приложения может проходить в соответствии со следующей итерационной схемой: • идентификация классов научных данных и алгоритмов, участвующих в постановке и решении задач моделирования и визуализации, на основе выделения ключевых абстракций предметной области; • определение семантики выделенных классов, установление отношений общности между ними, таких как «общее–частное», «целое–часть», построение объектных классификаций (иерархий наследуемых классов) для данных и алгоритмов с вершинами в суперклассах Data и Algorithm соответственно; • установление отношений использования между экземплярами классов на основе анализа семантической зависимости и представление их в виде типизированных входных, выходных и смешанных связей, выделение одиночных и множественных связей; • идентификация специфических атрибутов, свойств и поведения частных объектов, реализация их классов, для конкретных алгоритмических классов реализация специфических методов выполнения; • составление и тестирование различных сценариев работы с выделенной системой классов, возможное ее критическое переосмысление, выделение новых типов объектов и, как следствие, возврат к предыдущим этапам разработки. В исключительных ситуациях возможно расширение функциональности классов Scene, Object.
Законченное приложение включает объектно-ориентированное ядро, инвариантное по отношению к различным задачам и предметным областям, расширяемые библиотеки классов, специфичные для рассматриваемой прикладной области, и унифицированный графический интерфейс пользователя. В качестве стандартных инструментальных средств, допускающих перенос разрабатываемых приложений на различные аппаратные платформы с минимальными усилиями, могут использоваться язык программирования Си++, графическая библиотека OpenGL и стандартные интерфейсные библиотеки (такие как Motif, Qt, Gtk).Общая открытая модульная архитектура приложения приведена на рис. 3. Функциональность законченного приложения определяется главным образом подключаемыми прикладными библиотеками и семантикой их классов.
Рис. 3. Архитектура приложения
4. Система научной визуализации общего назначения OpenMV 4.1. Организация и состав системы В соответствии с предложенной методологией на платформе UNIX/X Window была реализована система визуализации общего назначения OpenMV (Open Modeler&Visualizer). Система позволяет пользователю воспроизводить различные виды физических явлений посредством визуализации и анимации предварительно подготовленных данных моделирования. Система обеспечивает визуализацию распространенных типов данных с использованием широкого набора методов в рамках произвольных сценариев, пользователем. Система задаваемых
129 включает описанное выше объектноориентированное ядро, расширенное библиотеками научных данных и методов научной визуализации, и унифицированный графический интерфейс пользователя. Библиотека научных данных построена как набор классов, производных от ядра и реализующих различные научные понятия, обычно используемые в приложениях вычислительной механики. Библиотека включает классы для манипулирования различными типами данных, такими как структурированные и неструктурированные поверхностные и объемные сетки, ломаные, наборы точек, физические поля, цветовые палитры, шкалы, наборы маркеров, ортогональные сечения, виды. Библиотека организована как единая иерархия конкретных и абстрактных классов, наследуемых от класса Data ядра системы. Фрагмент данной иерархии представлен на рис. 4.
трехмерных случаях и обеспечивающую их стандартное отображение в контексте OpenGL. Класс физических полей также поддерживает обобщенное многокомпонентное представление, которое может соответствовать скалярным, векторным и тензорным полям, заданным на различных типах многомерных геометрических данных. Методы отображения позволяют показывать произвольные геометрические данне как наборы точек, каркасное или твердотельное представление в соответствии с различными топологическими элементами (вершинами, ребрами, гранями). Закраска элементов может быть выполнена фиксированными цветами (правило закраски) или в зависимости от значений поля, заданных на выбранных элементах, а также указанной шкалы и цветовой палитры (правило псевдозакраски).
Рис. 5. Выдержка из иерархии классов библиотеки методов научной визуализации
Рис. 4. Выдержка из иерархии классов библиотеки научных данных Используемые абстракции позволяют манипулировать унифицированным образом различными геометрическими и топологическими типами данных. Все классы геометрических данных имеют обобщенную реализацию, позволяющую использовать их как в двумерных, так и в
Библиотека методов научной визуализации представляет собой набор производных от классов ядра алгоритмических классов, которые реализуют широко распространенные методы и способы, предназначенные для визуализации задач вычислительной механики. Библиотека включает классы для интерполяции полей, построения изолиний и изоповерхностей, конструирования линий и трубок тока, трассировки траекторий
130 частиц, конструирования ортогональных сечений, маркеров и вычисления норм полей. Библиотека построена как единая иерархия конкретных и абстрактных классов, наследованных от класса Algorithm ядра. Фрагмент иерархии классов представлена на рис. 5. Реализованный набор алгоритмов позволяет интерполировать поля, заданные на структурированных сетках, на любые другие структурированные сетки или произвольные геометрические данные; извлекать изолинии из скалярных полей, заданных на поверхностных сетках; извлекать изоповерхности из скалярных полей, заданных на структурированных объемных сетках; конструировать линии и трубки тока для стационарных векторных полей, заданных на структурированных сетках; трассировать траектории частиц для нестационарных векторных полей, заданных на структурированных объемных сетках; конструировать ортогональные сечения полей, заданных на структурированных объемных сетках; конструировать маркеры для скалярных и векторных полей, заданных на произвольных геометрических данных, вычислять различные нормы для полей. Кроме методов визуализации, данная библиотека обеспечивает специальные классы для растеризации геометрических данных в графическом контексте OpenGL в соответствии с заданными правилами закраски и псевдозакраски, а также вспомогательные классы для сохранения/восстановления объектов сцены в файлы/из файлов внутреннего формата и сохранение созданных изображений сцены в растровом формате PPM. Полнота включенных библиотек классов соответствует функциональности системы общего назначения и обеспечивает ее развитые возможности для визуализации широкого круга задач вычислительной механики, включая гидродинамику, химическую кинетику, релятивистскую механику и т.п. Интерфейс системы предоставляет унифицированные диалоги для составления и интерпретации сложных сценариев, а также для редактирования объектов, окна просмотра трехмерной сцены, меню и панели инструментов. Для ясности и удобства использования диалоги сцены отображают иерархию зарегистрированных в системе прикладных классов, диаграмму текущего сценария и отфильтрованный список объектов сценария. Для создания,
редактирования и связывания отдельного объекта внутри сценария пользователь устанавливает требуемые значения их открытых атрибутов и соединений через соответствующий унифицированный диалог редактирования. Унификация диалога достигается за счет применяемой спецификации атрибутов и соединений как членов классов данных и алгоритмов. Применяемая унификация интерфейса не препятствует его специализации для частных целей. Снимок экрана системы представлен на рис.6.
Рис. 6. Снимок экрана системы OpenMV с полученным изображением и диалогами редактирования объектов Через интерфейс пользователь выбирает соответствующий сценарий для изучаемой задачи, корректирует его параметры (уточняет параметры постановки задачи, настраивает используемые методы визуализации, устанавливает подходящие виды сцены, размещает источники света и т.д.), активизирует его и наблюдает возникающие и визуализируемые результаты как анимированное трехмерное изображение сцены. Итоговое изображение генерируется и анимируется посредством повторяющейся интерпретации выбранного сценария. Интерпретация может либо непосредственно инициироваться пользователем, либо осуществляться в результате некоторых изменений в сценарии, приводя к автоматическому обновлению итоговой сцены. Эта возможность позволяет интерактивно в визуальном режиме изучать решаемую задачу в зависимости от параметров ее постановки. Квалифицированные пользователи могут составлять собственные сценарии, интегрируя различные
131 компоненты моделирования и визуализации для изучения сложных процессов и явлений. В заключение перечислим основные возможности системы OpenMV. Как система визуализации общего назначения OpenMV обеспечивает: • визуализацию широко распространенных геометрических и физических типов данных, включая широкое множество сеток различной топологической организации, скалярных, векторных, тензорных полей, шкал, сечений и т.п.; методов • использование различных визуализации, включая извлечение изолиний и изоповерхностей, конструирование линий и трубок тока, отображение полей с применением методов стрелок, частиц, псевдозакраски; • визуализацию и анимацию сложных композиционных сцен; • интерактивное манипулирование отдельными объектами сцены; • написание и повторное использование сценариев для типовых задач визуализации; • сохранение используемых данных, методов и сценариев в файлах. Благодаря развитым возможностям, а именно: • комбинированию сценариев, определяемых пользователем, со встроенными; • объектно-ориентированному визуальному программированию сложных сценариев; • трехмерному многооконному интерфейсу; • манипулированию с многокомпонентными полями; • эволюции (адаптируемости, расширяемости) посредством расширения прикладных библиотек данных и алгоритмов, система предоставляет удобные и эффективные средства для построения специализированных интегрированных приложений моделирования и визуализации, включая системы CAD/CAM/CAE. Открытая архитектура системы позволяет расширять функциональность путем включения новых прикладных библиотек классов для представления научных данных и алгоритмов моделирования, специфичных для разрабатываемых приложений. Унифицированный пользовательский интерфейс может быть относительно просто модифицирован для приспособления к специфике приложений.
В следующем разделе мы обсудим эволюционные возможности системы OpenMV. 4.2. Некоторые примеры визуализации задач вычислительной механики Рассматриваемая система OpenMV может применяться для изучения широкого класса задач вычислительной механики c использованием различных сценариев визуализации. Построение конкретного сценария осуществляется путем конструирования экземпляров соответствующих научных данных и алгоритмов визуализации и установления связей между ними в соответствии с общей дисциплиной связывания объектов. В получаемое определенном смысле представление сценария напоминает диаграмму потоков данных в системах визуализации общего назначения, таких как AVS, Data Explorer, IRIS Explorer [9], за исключением того, что в нем непосредственно участвуют и сами преобразуемые данные. Интерпретация сценария выполняется путем повторяющейся последовательной активизации алгоритмов, которые должны быть предварительно упорядочены в соответствии с установленными отношениями зависимости между объектами сцены. Будучи последовательно активизированы, алгоритмы сценария конструируют новые объекты и обновляют существующие, приводя к получению итогового изображения в статическом режиме и к его анимации в динамическом режиме. Однажды сконструированный сценарий может быть впоследствии снова и снова применен для изучения аналогичной задачи. Разработанная система визуализации была успешно использована для изучения актуальных научных проблем, связанных с математическим моделированием сложных физических явлений, таких как: • экологические последствия процесса горения метана; • моделирование процессов переключения в полупроводниковых кристаллах с оптической бистабильностью; • обтекание открытой каверны набегающим потоком сверхзвукового газа. Более подробную информацию о данных приложениях, дополнительные изображения и фильмы, описания других задач, изученных посредством OpenMV,
132 можно найти в [10]. Строгая математическая постановка задач и детали численного моделирования приводятся в [11, 12]. Рассмотрим пример сценария визуализации результатов моделирования сверхзвукового потока вязкого газа над открытой прямоугольной каверной. Входными данными, поступающими от программы моделирования, являются регулярные сетки и заданные на них поля давления и скорости.
осуществляют их закраску в указанном виде. Порядок применения алгоритмов и получения промежуточных результатов легко прослеживается по диаграмме сценария, представленной на рис.7. Полученное итоговое изображение показано на рис. 8.
Рис. 8. Итоговое изображение для задачи динамики сверхзвукового газа
Рис. 7. Диаграмма сценария визуализации, предназначенного для изучения сверхзвукового потока вязкого газа над открытой прямоугольной каверной Для получения полной картины возвратного течения вблизи угла каверны применяется метод трассировки траекторий частиц. Частицы маркируются стрелками, окрашиваемыми в соответствии с амплитудой скорости. Для применения метода псевдозакраски исходное поле скорости интерполируется на набор частиц вычисляется норма поля, и соответствующая модулю скорости поля. Для информативности дополнительно визуализируется поле давлений с применением контурного метода. Правила отрисовки задаются как входные параметры алгоритмов отображения, которые выполняют совместный анализ геометрических объектов сцены и
Необходимо отметить, что большинство методов визуализации допускает обобщенную реализацию, не зависящую от конкретных типов входных данных. Например, в приведенном примере алгоритм выделения изолиний реализован с применением абстракции регулярных сеточных данных, на которых задано исходное скалярное поле. В этом случае алгоритм применим в равной степени как к равномерным, неравномерным ортогональным сеткам, так и к деформированным сеткам. Привлечение механизма абстрактных типов данных существенно облегчает построение сложных композиционных сценариев с использованием относительно небольшого репертуара методов. Данное обстоятельство оказывается существенным для функционального расширения открытой системы, поскольку добавление новых производных типов данных и алгоритмов не приводит к необходимости создания новых версий ранее реализованных классов. Другая задача связана с оценкой последствий процесса горения метана, имеющей важное экологическое значение. Фактор распространения потока воздуха является существенным для адекватного моделирования протекающих процессов химической кинетики для многокомпонентной реагирующей смеси. Рис. 9 демонстрирует потоки газа, воспроизведенные посредством линий тока и стрелок. Полученные линии тока и стрелки окрашены в соответствии с амплитудой скорости.
133 5. Некоторые специализированные интегрированные приложения моделирования OpenMV
Рис. 9. Итоговое изображение для задачи химической кинетики
Рис. 10. Итоговое изображение для задачи оптики Третья задача, связанная с моделированием процессов переключения в полупроводниковых кристаллах с оптической бистабильностью, является важной для конструирования новых полупроводниковых устройств, являющихся базой для будущих оптических ЭВМ и сетей. Процесс перехода распределения носителей заряда в оптических кристаллах в устойчивое состояние исследуется в зависимости от интенсивности лазерного излучения и диффузии носителей. Данный процесс визуализируется методом извлечения изоповерхностей (см. рис. 10). Прозрачные изоповерхности окрашены с использованием радужной палитры.
5.1. Динамика релятивистских струн Для изучения и иллюстрации теоретически установленных явлений динамики релятивистских струн [13] было разработано и реализовано в ОС UNIX/X Window специальное интегрированное интерактивное приложение как специализация системы визуализации общего назначения OpenMV. Данное приложение позволяет пользователю воспроизводить различные типы явлений динамики открытых и замкнутых струн посредством их моделирования, визуализации и анимации. Поскольку стандартная версия OpenMV предназначена для научной визуализации задач вычислительной механики и предоставляет развитые библиотеки научных данных и методов визуализации, данное специализированное приложение было разработано как эволюция стандартной версии OpenMV, расширенное прикладными библиотеками классов для задач динамики струн. Разработанная библиотека динамики струн включает специальные и универсальные классы алгоритмов, предназначенных для: • конструирования открытых и замкнутых струн с полями распределения плотности энергии и момента по заданным опорным кривым произвольной геометрии; • модификации структурированных поверхностных сеток путем добавления лент ячеек, основанных на заданной ломаной (для реконструкции мировых листов по обновленным открытым и замкнутым струнам); • конструирования мировых листов открытых и замкнутых струн с полями распределения плотности энергии и момента непосредственно по заданным опорным кривым; • интегрирования математических функций неявными методами Рунге– Кутта; а также вспомогательные классы данных для: • преобразования полей распределения плотности энергии и момента, заданных
134 на геометрических кривых, в математические функции; • манипулирования с опорными кривыми (NURBS). На рис. 11 приведен пример сценария, предназначенного для изучения задач динамики релятивистских струн. Данный сценарий определяет совокупность данных и алгоритмов, позволяющих пользователю устанавливать и редактировать опорные кривые, конструировать открытые и замкнутые струны, реконструировать соответствующие мировые листы и визуализировать полученные результаты одновременно в нескольких видах как анимированные трехмерные геометрические сцены, закрашенные в соответствии с распределениями плотности энергии и момента. Пользователь может легко модифицировать данный сценарий путем изменения значений атрибутов объектов, замены отдельных методов моделирования и визуализации другими или даже путем замены целых фрагментов, чтобы приспособить сценарий для конкретных целей.
Рис. 11. Диаграмма сценария для изучения задач динамики релятивистских струн с иерархиями используемых классов данных и алгоритмов Снимок экрана законченного интегрированного приложения приведен на рис. 12 для иллюстрации принципов
унификации пользовательского интерфейса. На рисунке показаны изображения, полученные в результате интерпретации описанного выше сценария. 5.2. Моделирование генератора с инерционной нелинейностью Следующий пример иллюстрирует, каким образом сложный сценарий, интегрирующий различные компоненты для геометрического моделирования, решения математических задач, визуализации и отображения, может составляться и интерпретироваться внутри приложения, построенного на основе описанного выше ядра, расширенного соответствующими прикладными библиотеками классов в соответствии с общей методологией. Представленный сценарий предназначен для изучения поведения генератора с инерционной нелинейностью. Моделью данного генератора является система обыкновенных дифференциальных уравнений (ОДУ) со странным аттрактором [14]. Для изучения поведения данной модели и определения притягивающей области в фазовом пространстве удобно сконструировать фазовые траектории, соответствующие различным начальным условиям задачи Коши. Множество начальных условий может быть задано посредством конструирования сложного твердого тела в интересующей области пространства в соответствии с твердотельной конструктивной геометрической моделью (CSG) [15] и генерирования точек на его граничном представлении. Затем множество задач Коши может быть решено численным методом, и полученные результаты могут быть визуализированы посредством окрашивания фазовых траекторий в соответствии с величинами производной. Для выявления свойств функции ОДУ может быть также сконструирована изоповерхность, соответствующая заданной величине производной. Данная изоповерхность выделяется из поля величин производных, определяемого по правой части системы ОДУ, реализуемой классом Attractor ⊂ Function. Описанный сценарий моделирования и визуализации показан на рис. 14, полученное итоговое изображение — на рис. 13.
135 являться как элементарные тела, так и сами операции, данные связи имеют тип CSGData.
Рис. 12. Снимок экрана приложения для изучения задач динамики релятивистских струн с полученными изображениями
Рис. 14. Диаграмма сложного сценария моделирования и визуализации, предназначенного для изучения поведения генератора с инерционной нелинейностью
Рис. 13. Итоговое изображение для задачи моделирования генератора с инерционной нелинейностью Обсудим достигнутые преимущества нашего подхода, ограничиваясь фрагментом сценария, связанным с геометрическим моделированием. CSG модель определяет сложное тело в терминах теоретикомножественных операций (объединение, вычитание, пересечение) над элементарными телами (параллелепипед, сфера, цилиндр, конус, призма, тор). CSG модель может быть естественным образом реализована в рамках предложенной методологии. Элементарные тела и теоретико-множественные операции должны рассматриваться как пассивные объекты, представленные классами CSGElement ⊂ CSGData ⊂ Data и CSGOperation ⊂ CSGData ⊂ Data соответственно. Геометрические элементы не имеют связей. Операции имеют пару входов, через которые они связываются с операндами. Поскольку операндами могут
Взаимодействуя друг с другом, как CSG элементы, так и операции способны классифицировать точки по принадлежности к соответствующим геометрическим телам. Для элементов подобная классификация основывается на простейших геометрических соотношениях, приписанных данному типу примитива, для операций — на логическом анализе результатов, полученных для каждого операнда. Результирующая операция соответствует сложному твердому телу, обладает необходимой функциональностью для классификации точки и может использоваться как часть более сложных сценариев. Обсудим фрагмент сценария, связанный с численным решением нелинейных дифференциальных уравнений. Неопределенный характер решения, связанный со свойствами жесткости, смешанным типом уравнений, их структурной разреженностью, приводит к необходимости изменения отдельных методов решения и применения различных вычислительных стратегий. Например, при решении жестких обыкновенных дифференциальных уравнений (ОДУ) обычно применяются неявные методы, реализация которых связана с решением нелинейных алгебраических уравнений на каждом шаге временной дискретизации [16].
136 Для решения последних методами ньютоновского типа необходимо применить тот или иной метод решения систем линейных алгебраических уравнений. Существенно, что выбор каждого метода решения может осуществляться независимо друг от друга и в конечном итоге определяется численными особенностями вспомогательных задач. Описанная редукционная схема решения систем ОДУ естественно реализуется в рамках обсуждаемой методологии. Методы решения систем ОДУ, нелинейных и линейных алгебраических уравнений представляются, соответственно, классами ODEImplicitAlgorithm, NewtonSolver, LinearSystemSolver, производными от Algorithm. Входами перечисленных алгоритмов являются данные, участвующие в математических постановках соответствующих задач, выходами — результаты их численного решения. Заметим, что входы и выходы задействованы только у основного алгоритмического объекта — метода решения системы ОДУ, который активизируется в результате наступления соответствующих событий в сцене. Отношения использования между остальными объектами-алгоритмами передают редукционные связи. Для алгоритмических объектов, участвующих в них, входы и выходы не определены, поскольку эти объекты используются друг другом, но не активизируются непосредственно сценой. Будучи разработанным в рамках системы OpenMV, расширенной классами для представления CSG модели и решения вычислительных задач, данный сценарий может быть гибко приспособлен к решению частных задач посредством модификации отдельных фрагментов, данных и алгоритмов. Единственное ограничение состоит в том, что изменяемые объекты должны удовлетворять установленной типизации связей. Данное свойство гарантирует, что тот же самый сценарий может корректно использоваться в комбинации с новыми типами данных и алгоритмов, расширяющими разработанные библиотеки классов. Объединяя достигнутые возможности объектноориентированной разработки прикладных библиотек классов, составления и модификации сложных сценариев, OpenMV обеспечивает широкие возможности повторного использования как разработанных компонентов программного
обеспечения, сценариев.
так
и
составленных
6. Заключение Таким образом, рассмотрена объектноориентированная методология для построения интегрированных приложений моделирования и визуализации. Данная методология обеспечивает общую дисциплину и гибкие программные средства для унифицированной разработки приложений в существенно различных научных и промышленных областях на единой концептуальной, инструментальной и программной основе. Разработанные приложения имеют общую открытую модульную архитектуру, которая включает ядро, полностью инвариантное расширяемые библиотеки прикладных классов и графический интерфейс пользователя. Функциональность созданного приложения определяется главным образом полнотой включаемых прикладных библиотек и семантикой их классов. В соответствии с предложенной методологией была реализована система научной визуализации общего назначения OpenMV под ОС UNIX/X Window. Система обеспечивает визуализацию и анимацию широко распространенных научных данных стандартными методами визуализации в рамках произвольных сценариев, определяемых пользователем. OpenMV обеспечивает представление различных типов научных данных, таких как сетки, поля, шкалы, палитры, изображения, а также реализует различные методы визуализации и отображения, включая методы извлечения изолиний и изоповерхностей, построения линий тока, маркеров, конструирования сечений, псевдозакраски. Открытая архитектура системы позволяет разрабатывать многочисленные интегрированные интерактивные приложения для изучения разнообразных физических задач. Область потенциальных приложений предложенной методологии чрезвычайно широка и может охватывать математическое моделирование, интегрированные системы CAD/CAM/CAE, технологии моделирования виртуальной реальности, анимационные системы. В дальнейшем планируется сосредоточить работу на создании законченных приложений в близких междисциплинарных областях.
137 Литература 1. STEP Product Data Representation and Exchange. ISO CD 10303-42, 1994. 2. The Virtual Reality Modeling Language. ISO/IEC 14772-1:1997. 3. OpenGL programming guide: the official guide to learning OpenGL, version 1.1/ Mason Woo, Jackie Neider, Tom Davis, 2nd ed. Addison Wesley, 1996. 4. MPI: A Message-Passing Interface Standard, Message-Passing Interface Forum, May 5, 1994. 5. Object-Oriented and Mixed Programming Paradigms: new directions in computer graphics / Peter Wisskirchen (ed.), Springer, 1996. 6. Семенов В.А. Объектная систематизация и парадигмы вычислительной математики. // Программирование. 1997, № 4, с. 14–25. 7. S.C. Bailin, An Object-Oriented Requirements Specification Method, Comm.ACM, Vol. 32, No. 5, 1989, pp.608–623. 8. G. Booch, Object Oriented Design With Applications, Behjamin/Cummings Publishing Company, 1991. 9. S. Belien et al. Comparison of Visualization Techniques and Packages with applications to plasma physics. http://www.sara.nl/Consumer.Report/ Report.html 10. The ISP RAS Scientific Visualization Group Home Page, http://www.ispras.ru/~3D 11. Chetverushkin B.N., Iakobovski M.V., Kornilina M.A., Malikov K.Yu., Romanukha N.Yu. Ecological after-effects numerical modelling under methane combustion. In: Mathematical Models of Non-Linear Excitations, Transfer, Dynamics, and Control in Condensed Systems and Other Media. Ed. By L.A Uvarova, A.E. Arinstein, and Latyshev. Plenum Press, New York, 1998. 12. Yu. N. Karamzin, T.A. Kudryashova, S.V. Polyakov and I.G. Zakharova. Simulation of 3D optical bistability problem on parallel computer systems. Matematicheskoe modelirovanie, in «Fundamental physical and mathematical problems and modelling of technical and technological systems» (ed. L.A.Uvarova), pp. 117-124. Published by Moscow state technology university «Stankin», Moscow, 1999. 13. V. Burkin, S. Klimenko, I. Nikitin. Visualization and animation of relativistic string dynamics, Programming and computer software, 1998, V.24, —¹ 6, pp. 320–328. 14. Анищенко В.С. Сложные колебания в простых системах. — М.: Наука, 1990. 15. Requicha A.A.G. and Voelcker H.B., Solid Modeling: Current Status and Research Directions. — IEEE CG.A., Vol.3, No.7, 1983, pp.25–37. 16. Арушанян О.Б., Залеткин С.Ф. Численное решение обыкновенных дифференциальных уравнений на Фортране. — М.: изд. МГУ, 1990.
Эффективные алгоритмы и их программные реализации Н.Н. Кузюрин, В.А. Захаров, А.Н. Холодов, Л.В. Шабанов, А.В. Шокуров
1. Введение Настоящая статья посвящена результатам, полученным в последнее время рядом сотрудников отдела математических методов и алгоритмов ИСП РАН в области разработки эффективных алгоритмов и их программных реализаций. Прежде чем описывать эти результаты, постараемся бросить общий взгляд на проблематику, связанную с разработкой и анализом эффективных алгоритмов, и отметить некоторые характерные тенденции, присущие ей в последнее десятилетие. При расчете любой математической модели явно или неявно присутствуют два этапа: построение математического (и по возможности эффективного) алгоритма для произведения ее расчета и его реализация в виде конкретного программного обеспечения [6]. Снижение вычислительных затрат возможно на любом из этих двух этапов, однако используемые при этом методы различны. В англоязычной литературе задачи построения и анализа алгоритмов с точки зрения их эффективности и практической целесообразности объединяются в раздел, называемый теорией алгоритмов (см., например, [41]), в то время как более абстрактными и математическими вопросами существования алгоритмов с теми или иными характеристиками занимается теория сложности вычислений (cм., например, [51]). В отечественной литературе эти две смежные дисциплины традиционно объединяются в одну, также называемую теорией сложности вычислений. Чтобы подчеркнуть, что выбор конкретной программной реализации выходит за рамки теории сложности, строящиеся в литературе эффективные алгоритмы обычно описываются на наиболее примитивном псевдоалгоритмическом языке. Проблема создания эффективной программной реализации данного алгоритма на конкретной вычислительной архитектуре называется отображением алгоритма на архитектуру вычислительной системы. Учет особенностей вычислительной системы (параллельность, конвейерность, наличие быстрого кэша и т.п.) позволяет иногда выиграть (или проиграть при неудачном их использовании) в эффективности в десятки или сотни раз. Эти проблемы зачастую не имеют решающего значения ввиду быстрого роста
производительности процессоров и объемов памяти и выступают на первый план лишь при решении трудоемких задач. К их числу относятся, например, NP-трудные задачи дискретной оптимизации, задачи линейного программирования большой размерности, задачи анализа огромных массивов информации (data mining) и т.п. Даже простая задача сортировки для огромных файлов становится сложной вычислительной задачей, требующей иногда десятков и сотен часов для ее решения и, соответственно, использования эффективных алгоритмов (подробнее об этом см. в разд. 2 настоящей работы). Кроме того, потребность в эффективности выступает на первый план при создании стандартного программного обеспечения, хотя и не требующего больших вычислительных затрат, но в силу постоянного и частого использования влияющего на общую производительность вычислительной системы. Эти вопросы затрагиваются в разд. 5 настоящей статьи, в котором приводятся результаты исследования эффективности отображения на архитектуру современных рабочих станций с конвейерной архитектурой программ прикладной статистики. Основная тенденция последних лет в разработке эффективных алгоритмов заключается в быстром развитии области дискретных алгоритмов. Их доля стремительно растет в последние годы. Проводится ежегодный симпозиум по дискретным алгоритмам (Simposium on Discrete Algorithms − SODA), на двух крупнейших ежегодных симпозиумах по проблемам Theoretical Computer Science (IEEE FOCS и ACM STOC) дискретные алгоритмы также бывают представлены достаточно широко. В последнее десятилетие главный прогресс в разработке эффективных дискретных алгоритмов (и не только их) связан с вероятностными алгоритмами, т.е. алгоритмами, использующими в процессе своей работы результат случайного бросания монеты (или, как говорят, случайные биты информации) [53]. Такие алгоритмы, хотя и не подпадают под классическое определение алгоритма [1], являются, на самом деле, весьма практичными. Для огромного числа задач удается разработать более эффективные вероятностные алгоритмы (по сравнению с детерминированными) или, по крайней мере, гораздо более простые по структуре и реализации [53].
139 Одними из наиболее широко распространенных математических моделей, описывающих самые разные процессы реальности, являются линейное и целочисленное программирование [26]. Теория двойственности и симплекс-метод составляют краеугольные камни в этой области, опираясь на которые удалось решить огромное число практических задач оптимизации. Однако, несмотря на эти успехи, в последние годы линейное программирование (ЛП) переживает период стремительного развития. Это началось с осознания [46] того факта, что, несмотря на свою практичность, симплекс-метод не является эффективным на любых исходных данных, а только на подавляющей доле их (или другими словами не является полиномиальным алгоритмом). Первый полиномиальный алгоритм для задачи линейного программирования предложил Л.Г. Хачиян [29]. Его работа послужила стимулом для создания большого количества полиномиальных алгоритмов решения ЛП-задач, использующих так называемый метод внутренней точки [25], [45] и конкурирующих на практике с симплекс-методом. Затем были разработаны еще более эффективные алгоритмы, которые находят приближенные решения с гарантированными оценками точности, причем точность выступает как параметр алгоритма [66]. Для задач ЛП с неотрицательными исходными данными были разработаны параллельные алгоритмы, трудоемкость которых уже близка к неулучшаемой [52], [37]. Как отмечается в разделе 2 настоящей работы, эти алгоритмы (или их модификации) обладают еще одним замечательным свойством − являются коммуникационно-эффективными. Значимость новых эффективных алгоритмов для задач ЛП еще более возросла, когда было понято, что для решения существенно более сложных задач ЛП с ограничением, что переменные целочисленны (т.е. задач целочисленного линейного программирования − ЦЛП), можно с успехом применять метод вероятностного округления нецелочисленного решения их линейной релаксации (то есть той же задачи ЛП без ограничения целочисленности переменных) до целочисленного. Впервые этот метод построения эффективных вероятностных алгоритмов с гарантированными оценками точности был предложен в [56], а вскоре был разработан метод их дерандомизации, т.е. конвертирования таких вероятностных алгоритмов в детерминированные [57], [18]. Этот метод стал весьма широко использоваться и получил название метод условных вероятностей. Применительно к ЦЛП эти методы рассматривались в работах [18], [57], [19], [64]. На их основе для задач ЦЛП с неотрицательными данными удалось построить приближенные алгоритмы с неулучшаемыми гарантированными оценками точности. Однако для
задач ЦЛП общего вида эти вопросы еще мало исследованы и представляют весьма интересное и перспективное направление. Этой проблематике посвящен разд. 4 настоящей статьи. Там же рассматриваются и близкие вопросы о явных конструкциях различных объектов, понимаемых как эффективные алгоритмы их построения. Одним из современных направлений исследований является разработка так называемых коммуникационно-эффективных алгоритмов [42]. Его актуальность объясняется широким распространением параллельных и распределенных вычислительных систем различных типов и тем фактом, что коммуникационные затраты в них зачастую намного превосходят собственно вычислительные. Этим вопросам с точки зрения коммуникационной сложности [47] посвящен разд. 2 настоящей работы. Во многих приложениях возникает задача нахождения коэффициентов разложения функции по некоторому базису, если известно разложение этой функции по другому базису. По-видимому, самым известным и практически используемым разложением такого рода является дискретное преобразование Фурье. Наличие эффективного алгоритма или быстрого преобразования Фурье сделало его использование чрезвычайно широким. Имеется, однако, много других классических базисов из ортогональных многочленов, также требующих разработки соответствующих эффективных алгоритмов разложения. Этой проблематике и достигнутым в ней результатам посвящен разд. 6 настоящей работы. В заключительном разделе кратко рассмотрены алгоритмические вопросы формального анализа программ.
2. Коммуникационно-эффективные алгоритмы В связи с широким распространением глобальных телекоммуникационных сетей актуальность приобретает разработка эффективных методов решения задач оптимизации, когда различные части данных могут находиться в весьма удаленных друг от друга местах. Одним из естественных подходов к решению таких задач является использование локальных алгоритмов. Теория локальных алгоритмов была разработана Ю.И. Журавлевым еще в конце 50-х годов в связи с исследованием сложности решения так называемых переборных задач [9]-[11] и доказательством их неразрешимости в классах алгоритмов с ограничениями. В последние годы этот подход использовался при нахождении точности, которой можно достигнуть локальными алгоритмами в задаче линейного программирования [55].
140 2.1 Оценка точности распределенного решения задач ЛП и ЦЛП с точки зрения коммуникационной сложности Мы исследовали подход к оценке точности распределенного решения задач ЛП и ЦЛП с точки зрения коммуникационной сложности [47]. При этом предполагается, что исходные данные распределены между двумя пользователями, каждый из которых знает только свою часть данных. Под коммуникационной сложностью задачи понимается минимальное по всем алгоритмам, обеспечивающим нахождение решения, число пересылаемых битов. Важно отметить, что нами рассматривались приближенные алгоритмы и изучался вопрос соотношения точности и коммуникационной сложности. Рассматривалась задача целочисленного линейного программирования max cx (1) Ax ≤ b, x ≥ 0 – целые с m×n матрицей ограничений A, состоящей из неотрицательных элементов, пронормированных так, что aij≤1. Линейная релаксация задачи (1) отличается от нее отсутствием требования целочисленности переменных max cx (2) Ax ≤ b, x≥ 0. Предположим, что каждый из пользователей знает лишь половину матрицы A (а именно, 1-й пользователь знает столбцы с номерами {1, ..., n/2}, а второй − с номерами {n/2+1,..., n}), и оба знают целевую функцию и правую часть ограничений. Как они могут решить эту распределенную задачу, по возможности минимально общаясь между собой? Иначе говоря, вопрос заключается в определении точности, с которой распределенную задачу можно решить с заданной коммуникационной сложностью. Назовем число r мультипликативной точностью алгоритма, если всякое решение задачи, полученное с его помощью, отличается от оптимума не более чем в r раз. Алгоритм называется ε-оптимальным, если он гарантирует мультипликативную точность 1 + ε. Имеется тривиальная стратегия, при которой исходные данные от второго пользователя пересылаются к первому, который и находит точное решение задачи. Коммуникационная сложность при этом определяется пересылкой половины элементов матрицы ограничений. Имеются также простые стратегии (назовем их стратегиями 1 и 2 соответственно). Стратегия 1 заключается в том, что каждый пользователь решает усеченную задачу (1) со своим блоком столбцов, своими переменными и правой частью b, а затем из найденных значений выбирается максимальное. Остальные переменные при этом полагаются равными нулю. Тогда допустимость полученного решения очевидна, а
коммуникационная сложность есть O(log(1+z)) , где z − величина оптимума (1). Стратегия 2 заключается в том, что каждый пользователь решает усеченную задачу (2) со своим блоком столбцов, своими переменными и правой частью b/2. Допустимость полученного решения очевидна, а коммуникационная сложность при этом равна нулю. При условии неотрицательности исходных данных нетрудно доказать следующее Утверждение. Стратегия 1 (соответственно, 2) распределенного решения гарантирует для задачи (1) (соответственно, (2)) мультипликативную точность 2. Таким образом, имеется стандартная стратегия пересылки всех данных из одной части в другую, которая дает точное решение, но имеет большую коммуникационную сложность. И есть простые стратегии (1 и 2), которые имеют небольшую коммуникационную сложность, но не гарантируют нахождение решения с наперед заданной точностью. В результате наших исследований доказано существование стратегий решения задач ЛП и ЦЛП с неотрицательными данными, существенно более экономных по критерию коммуникационной сложности, чем стандартные. Сформулируем некоторые из полученных результатов. В [20] доказаны следующие утверждения. 1. Любая стратегия решения распределенной задачи (2), имеющая коммуникационную сложность не более m, не может гарантировать мультипликативную точность менее 2. Таким образом, имеется нижняя граница для всех алгоритмов. Оказывается, что существенно улучшить ее нельзя. 2. Для любого фиксированного ε>0 существует εоптимальный алгоритм решения задачи (2), имеющий коммуникационную сложность O(m (log nm)const). Эта верхняя оценка отличается от нижней оценки m только полилогарифмическим множителем. Таким образом, алгоритм имеет близкую к минимальной коммуникационную сложность, т.е. является коммуникационноэффективным. Оказалось, что свойством коммуникационной эффективности обладают и новые параллельные ЛП-алгоритмы [52], [37]. Модификация последнего алгоритма, существенно снижающая общее число выполняемых операций, предложена в [27]. Для задачи ЦЛП (1) в [22] построен детерминированный алгоритм нахождения приближенного целочисленного решения с гарантированными оценками точности и коммуникационной сложности. Более точно, доказано следующее: 3. Для любого фиксированного ε > 0
существует полиномиальный алгоритм решения распределенной задачи (1), который при условии (при n → ∞ ) log m=o(mini bi)
141
гарантирует мультипликативную точность 1+ε и имеет коммуникационную сложность O(m(lognm)const). Этот алгоритм основан на процедуре независимого (в каждой части) вероятностного округления нецелочисленного решения линейной релаксации до целочисленного с последующей дерандомизацией. Отметим, что условие, при котором доказано существование коммуникационно-эффективного алгоритма решения задачи ЦЛП (1), является стандартным достаточным условием близости целочисленного оптимума и оптимума линейной релаксации [18], [65], [36]. 2.2 Коммуникационно-эффективный алгоритм внешней сортировки Сортировка больших файлов всегда была важной практической задачей обработки информации. В последние годы к категории "больших файлов" принято относить файлы, имеющие размер в несколько сотен мегабайт. Теперь к реальным задачам относится и сортировка "сверхбольших файлов", размер которых составляет один и более терабайт. Некоторое представление о возможностях современной вычислительной техники дает время сортировки (2,5 часа) файла, содержащего 10000000000 100-байтных записей (ключи длиной в 10 байт имеют равномерное распределение). Эта сортировка была выполнена на 32 процессорах параллельной машины Origin2000. При этом использовалось 8 GB основной памяти и 559 4 GB дисков. Высокая скорость сортировки на современных параллельных машинах (распределенных вычислительных системах, системах с массовым параллелизмом, машинах с общей памятью и др.) может быть достигнута благодаря использованию эффективных параллельных алгоритмов сортировки. Особое место среди них занимают алгоритмы внешней сортировки. На эффективность алгоритмов параллельной сортировки сильное влияние оказывают коммуникационные затраты, которые неизбежны на фазе слияния отсортированных блоков данных и которые могут оказаться преобладающими в алгоритмах сортировки слияниями. Построению и анализу эффективных в смысле коммуникационных расходов алгоритмов сортировки посвящено немало научных статей (например, [42]). Интересно, что вопросы минимизации коммуникационных затрат в параллельных сортировках близки к вопросам минимизации количества обменов с внешней памятью (как правило, с памятью на дисках) для внешних сортировок. Последнее обстоятельство мотивировало проведение нашего исследования подходов к построению эффективных внешних сортировок.
В результате исследований способов построения коммуникационно-эффективных внешних сортировок Л.В.Шабановым была предложена схема внешней сортировки, в которой при некотором заданном размере основной памяти количество промежуточных записей и считываний ключей (и связанных с ними данных) было сведено к минимуму. В предложенной схеме использован только один вспомогательный файл, размер которого равен размеру исходного (сортируемого) файла. Сортировка проходит в два шага. На первом производится считывание исходного файла, разбиение его на блоки равной длины, внутренняя сортировка каждого блока и запись упорядоченных по ключам блоков в один промежуточный файл. Известно, что эффективность внутренней сортировки существенно влияет на эффективность внешней сортировки. Предварительный анализ и эксперименты показали, что в случае 32-разрядных целочисленных ключей значительным преимуществом (более чем в два раза) по сравнению с другими традиционными методами (быстрая сортировка, пирамидальная сортировка и др.) обладает поразрядная сортировка. Для 64разрядных ключей преимущество менее значительно (примерно в 1,5 раза). На втором шаге внешней сортировки производится слияние упорядоченных блоков. Для слияния Л.В.Шабановым предложена простая схема, которая реализует поиск и считывание сравнительно коротких упорядоченных последовательностей ключей из промежуточного файла в специальный буфер и слияние этих последовательностей с помощью динамической структуры данных (АВЛ-дерева). Таким образом производится слияние и вывод (запись в выходной файл) небольших упорядоченных по ключам последовательностей записей. Подкачка данных в буфер производится по сигналу схемы слияния в моменты, когда для выполнения слияния необходима новая порция данных, содержащихся в промежуточном файле. Следует отметить, что вместо АВЛ-деревьев для слияния отсортированных подпоследовательностей можно использовать другие способы и средства. Например, некоторая модификация поразрядной сортировки будет более эффективным способом реализации слияния для случая сортировки больших файлов, когда длины сливаемых последовательностей сравнительно велики (десятки и сотни тысяч элементов). Результаты проведенных нами экспериментов показали, что предложенная Л.В.Шабановым схема внешней сортировки позволяет эффективно сортировать большие исходные файлы с использованием одного промежуточного файла при минимально возможном количестве промежуточных записей и считываний (одна запись и одно считывание на ключ). При этом для сортировки достаточно выделить небольшой
142 сегмент основной памяти. Высокая эффективность сортировки сохраняется, например, в случае когда размер выделяемой основной памяти в 50 раз меньше размера в байтах исходного файла. Экспериментальное исследование также показало, что по производительности предложенный алгоритм не уступает лучшим коммерческим продуктам в данной области. Основной задачей дальнейшего исследования предложенной схемы внешней сортировки является ее оптимизация, т.е. выбор параметров, доставляющих наибольшую эффективность при заданных ограничениях (например, при заданном размере выделяемой для внешней сортировки основной памяти).
3. Методы дерандомизации, явные конструкции и эффективные алгоритмы Исследования, проводимые в последние десятилетия, продемонстрировали исключительную силу вероятностных методов и вероятностных алгоритмов [34], [53]. Идея аппроксимации различных классов целочисленных линейных программ путем нового способа округления − вероятностного округления, оказавшаяся чрезвычайно продуктивной, была предложена в [56]. Для положительного вещественного числа v идея состоит в том, чтобы рассматривать его дробную часть как вероятность, округляя v до └v┘ + 1 с вероятностью v−└v┘, и округляя v до └v┘ с вероятностью 1−(v−└v┘). Важным свойством такого округления является то, что математическое ожидание при этом равно v. Как это можно использовать для нахождения приближенных решений задачи ЦЛП (1)? Пусть найдено решение ее линейной релаксации x* =(x1, ..., xn) и значение оптимума этой линейной программы есть q. Положим xi=xi/k, где k − некоторый параметр, значение которого будет выбрано далее. Определим случайный вектор z ∈ Zn следующим образом. Независимо для каждого i положим zi равным └xi┘+1 с вероятностью pi=xi −└xi┘, и xi − с вероятностью 1 − pi = 1 − (xi − └xi┘). Используя такие округления, для задач ЦЛП с неотрицательными данными удалось построить приближенные алгоритмы с неулучшаемыми оценками точности [18], [57], [19], [64]. Однако для задач ЦЛП общего вида эти вопросы еще предстоит исследовать. Исследование возможностей вероятностных методов в задачах ЦЛП общего вида и выделение классов задач ЦЛП, для которых вероятностные округления дают нетривиальные гарантированные оценки точности, является важным как с теоретической, так и с практической точек зрения. Некоторые результаты в этом направлении получены в [19] и [35]. В [57], [18] независимо был разработан метод дерандомизации, т.е. конвертирования
соответствующих вероятностных алгоритмов в детерминированные. Этот метод в последние годы широко и успешно использовался при построении детерминированных алгоритмов для различных задач и получил название метод условных вероятностей (см. [53]). Поскольку алгоритмы вычисления условных вероятностей (на которых базируется построение детерминированного алгоритма) в [57] и [18] кардинально различны, интерес представляет нахождение близких к оптимальным алгоритмов вычисления условных вероятностей в задачах ЦЛП. Алгоритм из [57] применим только для задач ЦЛП с 0−1 коэффициентами и имеет сложность O(mn) (в модели unit-cost RAM, т.е. в числе арифметических операций) и не переносится прямо на задачи более общего вида. Алгоритм сложности O(mn2logm) для вычисления условных вероятностей по схеме [57] для задач ЦЛП с произвольными неотрицательными коэффициентами был предложен в [65]. Алгоритм из [18] (см. также [21]) для тех же задач имеет сложность O(mn2) (при любой фиксированной точности ычислений). Любой прогресс в уменьшении сложности вычисления условных вероятностей и приближение к сложности вида O(mn) представляет несомненный интерес и перспективное направление в области разработки эффективных алгоритмов. Как мы уже упоминали, ввиду широкого применения вероятностных методов, многие результаты в комбинаторике, теории чисел, теории графов являются неконструктивными. Поэтому все большее внимание уделяется построению так называемых явных конструкций и технике дерандомизации [54]. Обычно под явной конструкцией некоторого множества понимается эффективный алгоритм построения этого множества (или произвольного его элемента). Таким образом, здесь мы также сталкиваемся с необходимостью разработки эффективных алгоритмов. Это направление находится в стадии зарождения и успехи его еще не столь заметны. Однако потребность в нем стимулируется практикой, что сделало его весьма популярным [34], [54]. В частности, в теории конечных полей, являющихся базой современной криптографии и теории кодирования, большинство конструкций не являются явными в этом смысле (например, неизвестны эффективные алгоритмы нахождения по данному числу близкого к нему простого, построения конечного поля заданного размера и т.п. [62]). Поэтому обычно используют заранее найденные таблицы (например, таблицу простых чисел, не превосходящих заданного числа), что приводит к неуниформности конструкции. К тому же, этот подход накладывает естественные и довольно жесткие ограничения на величину рассматриваемых чисел.
143 В [63] (см. также [62]) получен интересный результат, который открывает новые возможности в построении явных конструкций, использующих конечные поля. Для данного числа Q за полиномиальное время (от logQ) там построено конечное поле размера q, причем q ∼ Q при Q → ∞. Однако области применения этого результата еще предстоит найти, что представляется интересной проблемой для исследования. Ведь все конструкции, использующие большие простые числа, являются неуниформными (например, широко известная криптосистема RSA), и нахождение униформных аналогов (или явных конструкций) представляет несомненный интерес. В этой связи упомянем результат [50], дающий явную конструкцию так называемых асимптотически хороших упаковок − классических комбинаторных объектов, существование которых было доказано в 1985 г. В. Редлем (см. [34]). В заключение этого раздела, посвященного возможностям вероятностных методов и алгоритмов, упомянем новое направление − вероятностные алгоритмы для квантовых компьютеров − сравнительно новой вычислительной модели, введенной в рассмотрение в 1985 г. В отличие от многих других моделей вычислений квантовые компьютеры в принципе физически реализуемы. В то же время, есть много указаний на то, что по своей силе (вычислительным возможностям) они могут значительно превосходить обычные. Особенно яркий пример этого содержится в [61], где предложены вероятностные алгоритмы нахождения дискретных логарифмов и факторизации целых чисел (разложения на простые множители), имеющие полиномиальную по числу бит трудоемкость. Эти две задачи обычно рассматриваются как вычислительно трудные (для них неизвестны полиномиальные алгоритмы) и на них базируются многие современные криптосистемы (например, криптосистема RSA). Нахождение других задач, эффективно решаемых вероятностными алгоритмами на квантовых компьютерах (типа проверки изоморфизма графов или какой-либо NP-полной задачи), является, несомненно, одной из важных и интересных проблем в области разработки эффективных алгоритмов.
4. Опыт решения задач вычислительной геометрии 4.1. Задача линейного программирования фиксированной размерности За последние годы было предложено большое число эффективных рандомизированных алгоритмов решения задач комбинаторной оптимизации и вычислительной геометрии. Один из таких алгоритмов − это алгоритм Кларксона [40], решающий задачу линейного программирования с n ограничениями и d
переменными в среднем за время O(n), при условии, что d является константой. Этот алгоритм и его модификации использовались нами как основа для разработки эффективных алгоритмов и программ для решения ряда задач вычисительной геометрии: задачи нахождения для заданного политопа вписанного шара максимального объема, нахождения крайних точек множества в d-мерном пространстве и т.д. Рассматривается задача линейного программирования фиксированной размерности cx → min (3) Ax ≥ b, где c, x – d-мерные векторы, A − n×d матрица. Алгоритм Кларксона вычисляет оптимум (3) следующим образом. Если n ≤ cd, то оптимум находится с помощью симплекс-метода. Если n > cd, то повторяется следующее с V0 (первоначально пустым): пусть S обозначает множество линейных неравенств в (3), R ⊂ S \ V0 − случайное подмножество размера r. Пусть x0 ← x0 (R ∪V0) − решение задачи ЛП с множеством неравенствограничений R ∪ V0, определенное рекурсивно, и пусть V − множество ограничений, нарушаемых x0. Если |V| > 2√n, то сделать новую попытку с новым подмножеством R, повторяя до тех пор, пока |V| ≤ 2√n. Включить заключительное множество V в V0. Когда V пусто, остановиться и выдать x0 в качестве искомого оптимума x0(S). В противном случае повторять вычисления в цикле. Модифицированный алгоритм [48] решения ЛП-задачи (3) имеет схожую структуру. Основное отличие заключается в выборе и добавлении только одного неравенства, максимизирующего невязку среди невыполненных ограничений. Как показано в [48], этот алгоритм допускает естественное распараллеливание и весьма эффективен на случайных данных. 4.2. Построение диаграммы Вороного и нахождение крайних точек в пространствах фиксированной размерности Разработанный С.А. Мартишиным [23] быстрый алгоритм нахождения крайних точек множества в D-мерном евклидовом пространстве основан на использовании модифицированного алгоритма Кларксона [40], [48] решения задачи линейного программирования в пространствах фиксированной размерности и использовании некоторых просто проверяемых достаточных условий, позволяющих существенно повысить эффективность алгоритма. Программная реализация и эксперименты показали, что в пространствах размерности до 1015 крайние точки множеств находятся гораздо эффективнее, чем при использовании стандартных алгоритмов, основанных на построении выпуклой оболочки. Разработан также новый динамический алгоритм построения и вычисления некоторых
144 характеристик ячеек диаграммы Вороного на плоскости с ограничениями, весьма эффективный для данных, распределение которых близко к равномерному [24].
5. Эффективная реализация пакета прикладной статистики на конвейерных ЭВМ Статистические методы решения прикладных задач − от моделирования плазмы до проверки простоты чисел − используют генераторы случайных последовательностей и требуют большого объема вычислений. Поэтому генераторы таких чисел должны работать с максимальной производительностью. Основное препятствие на этом пути − использование точных целочисленных вычислений с многоразрядными числами. В [30], [31] разработаны быстрые алгоритмы генерирования псевдослучайных последовательностей, использующие по возможности минимальное число операций целочисленного умножения. Разработаны [30] методы повышения эффективности решения задач статистической обработки больших объемов данных и нахождения функции распределения по данным. Предложена схема сдваивания для сложения массивов и исследована ее эффективность при отображении на конвейерные архитектуры. Важной компонентой большинства статистических пакетов является эффективное вычисление функций распределения случайных величин. В [30] предложен алгоритм быстрого вычисления функции распределения, основанный на таблично-аппроксимационном методе [32]. Предложенные алгоритмы позволили решить задачу эффективной реализации на языке FORTRAN пакета математической статистики на RISK процессоре ALPHA EV-4. В работе [30] описаны методы ускорения программных реализаций алгоритмов, учитывающие архитектурные особенности используемого процессора. Процессор EV-4 предоставляет возможность параллельного использования операций, исполняемых различными функциональными устройствами. Устройства целочисленной и плавающей арифметических операций конвейеризованы. Имеется также быстрая кэш-память. Однако не все арифметические операции конвейеризованы. Среди таких операций − целочисленное умножение и деление чисел с плаваюшей запятой. Максимальная производительность программ достигается за счет максимальной загрузки конвейеров функциональных устройств и максимального использования возможностей иерархической памяти (регистров и быстрой кэшпамяти). В работе [30] описаны результаты оптимизации программ на языке FORTRAN для некоторых задач
математической статистики на процессоре ALPHA EV-4. Приведенные результаты временных тестов для оценки производительности программных реализаций показывают значительный рост производительности оптимизированных программ.
6. Быстрые алгоритмы разложения полинома по последовательностям ортогональных полиномов Во многих приложениях возникает задача нахождения коэффициентов разложения функции по некоторому базису, если известно разложение этой функции по другому базису. Наиболее важными являются следующие примеры: полиномиальная интерполяция, преобразования Фурье и другие ортогональные преобразования, разложение по собственным векторам ленточных матриц, разложение по собственным функциям циклических операторов. Все эти проблемы могут быть сведены к проблеме умножения N×N матрицы на N-мерный вектор. В общем случае для этого необходимо O(N2) арифметических операций [1]. Однако для некоторых матриц, зависящих от O(N) параметров, существуют быстрые алгоритмы умножения с O(NlogαN) арифметическими операциями. Такими матрицами являются, например: матрицы дискретного преобразования Фурье, матрицы ортогональных преобразований, циркулянты, теплицевы матрицы, матрицы Вандермонда и матрицы Коши. Обычно быстрый алгоритм основан на тождествах для умножаемой матрицы. Например, алгоритм быстрого преобразования Фурье основан на некоторых тождествах для матриц Фурье. Быстрый алгоритм для вычисления значений полинома и значений его производных основан на следующем разложении треугольника Паскаля: || C ij ||= Diag ( n! ) || t ij || Diag ( n! ) − 1 где Diag(n!) является диагональной матрицей Diag(n!)i,j=i!δi,j, а ||tij|| является теплицевой матрицей с элементами tij=1/(i−j)!, если i≥j; tij=0, если i<j. Напомним, что матрица называется теплицевой, если ее элементы, расположенные на прямых, параллельных главной диагонали, равны. Быстрый O(NlogN)−алгоритм для умножения теплицевой матрицы на вектор основан на том, что теплицева матрица представляется как произведение двух циркулянтов. Циркулянтом называется такая матрица C, для которой cij=cpq, если i−j ≡ p−q mod N. Задача умножения циркулянта C на вектор x эквивалентна вычислению циклической cвертки Conv(c,x)=FN-1(FNc FNx), где − операция покомпонентного умножения векторов.
145 Быстрый алгоритм разложения по собственным векторам якобиевой матрицы основан на представлении такой матрицы как самосопряженной одноранговой модификации прямой суммы двух якобиевых матриц половинного порядка. Это представление приводит к O(Nlog3N)−алгоритму умножения вектора на матрицу собственных векторов якобиевой матрицы. Похожее соотношение для самосопряженных ленточных матриц дает быстрый алгоритм умножения вектора на матрицу ее собственных векторов. Быстрый алгоритм для разложения полинома по ортогональным многочленам следует из упомянутых выше быстрых алгоритмов и из того факта, что такие ортогональные полиномы удовлетворяют трехчленному рекуррентному соотношению и поэтому являются собственными векторами якобиевой матрицы. Все упомянутые выше задачи являются специальными случаями следующей задачи разложения по полиномиальному базису. Пусть R[x] обозначает векторное пространство полиномов над полем R нулевой характеристики. Тогда любая последовательность полиномов {pn(x)}, n≥0 с условием deg pn(x)=n является базисом этого векторного пространства. Задача разложения по полиномиальному базису состоит в следующем: дано разложение полинома p(x) = ∑anpn(x), найти разложение p(x) = ∑bnqn(x). Обычно либо pn(x) = xn, либо qn(x) = xn. Последовательность полиномов {sn(x)} с производящей функцией S(x,t) = sn(x)tn называется последовательностью Боаса-Бака [38], [58], если и только если S(x,t) = g(t)Ψ(xf(t)), где g(t), Ψ(t), f(t) − формальные ряды такие, что f(0) = 0, f'(0) = g(0) = 1. Этот класс последовательностей полиномов часто называется последовательностями обобщенного типа Аппеля [5], [7], [60]. Многие известные последовательности полиномов являются последовательностями БоасаБака [5], [38], [58], [59]. В частности, классические ортогональные полиномы (вместо полиномов Якоби
Pnα ,β ( x ) α ,β
необходимо
Pn ( x + 1)),
рассмотреть
полиномы
Бесселя,
полиномы полиномы
Бернулли и многие другие имеют производящую функцию Боаса-Бака. Теневой анализ изучает общие свойства последовательностей полиномов Боаса-Бака ([7], [60], 59]). Задача разложения полинома p(x) по последовательности Боаса-Бака {sn(x)} может быть сведена к задаче умножения вектор-строки коэффициентов многочлена на теневую матрицу M(f(t),g(t)). Элементами k-го столбца теневой матрицы являются коэффициенты ряда g(t)f(t)k. Последовательность полиномов Боаса−Бака с f(t) = t называется последовательностью Бренке [38]. Для таких последовательностей теневая матрица является теплицевой. Это позволило
получить результат [28], что сложность разложения данного многочлена по последовательности полиномов Бренке равна O(NlogN). С использованием того факта, что последовательности полиномов Эрмита и Лагерра являются последовательностями Бренке, в [28] получены быстрые алгоритмы разложения данного полинома по полиномам Эрмита и Лагерра. В общем случае пока не найден быстрый алгоритм умножения вектор-строки на теневую матрицу. Однако в [28] найден приближенный O(Nlog2N)−алгоритм умножения теневой матрицы на вектор-столбец, который находит искомое произведение с любой наперед заданной точностью.
7. Алгоритмические вопросы формального анализа программ В последнее время В.А.Захаровым получен ряд результатов, касающихся применения методов математической логики для анализа поведения параллельных распределенных программных систем. В [16, 67] рассмотрены две наиболее употребительные семантики параллельных вычислений − семантика чередования и семантика частичного порядка. При использовании логических методов верификации параллельных и распределенных программ множеству вычислений в зависимости от выбора семантики сопоставляется модель (или множество моделей) в одной из неклассических логик − темпоральной логике или логике причинности. Поскольку эффективность алгоритмов анализа спецификаций параллельных вычислений существенно зависит от размера модели, выбор подходящей логики следует осуществить таким образом, чтобы объем рассматриваемой модели был наименьшим. В данных работах исследуются необходимые и достаточные условия, при которых множество вычислений параллельной программы в семантике чередования может быть полностью и однозначно описано единственной моделью меньшего объема в семантике частичного порядка. В [68] разработан новый подход к проверке выполнимости формул пропозициональной темпоральной логики линейного времени (PLTL). Начиная с основополагающих работ Манны и Пнуели, эта логика широко применяется для спецификации распределенных систем программ. Благодаря значительным выразительным возможностям этой логики многие свойства, описывающие поведение сложных реагирующих программных систем могут быть представлены формулами PLTL. Таким образом, задача верификации взаимодействующих программных систем может быть сведена к проблеме выполнимости в PLTL. В предложенном алгоритме проверка выполнимости формул PLTL осуществляется путем символьной манипуляции с
146 монотонными дизъюнктивными нормальными формами, используя технику представления ДНФ контактными схемами. В [17] рассматривается задача проверки выполнимости формул логики ветвящегося времени CTL на конечных моделях и предлагается новый оптимальный по быстродействию алгоритм ее решения. Практическая применимость алгоритма продемонстрирована на примере анализа системы взаимодействующих процессов, осуществляющих сортировку. В.А. Захарову в серии работ [12, 13, 14, 15, 16, 67, 68, 17] удалось разработать общий подход к построению эффективных (в том числе полиномиальных) алгоритмов разрешения проблемы эквивалентности в различных классах программ. Проблема эквивалентности программ явно или опосредованно возникает при решении многих задач системного программирования, к числу которых относятся задачи трансляции, оптимизации и верификации вычислительных программ, разработка методов частичных вычислений, задачи специализации и повторного использования программ и др. Всякий раз, когда возникает необходимость изменить синтаксическую составляющую вычислительной программы (текст программы), сохраняя при этом в той или иной мере ее семантическую компоненту (поведение, или функционирование), приходится иметь дело с отношением эквивалентности на множестве программ и, следовательно, с проблемой эквивалентности программ. Необходимость исследования свойства программных вычислений, наряду с проблемами синтаксического анализа и перевода, послужила источником многочисленных моделей вычислений, получивших широкое распространение и применение в современном программировании. Наиболее общая формулировка проблемы эквивалентности такова. Для произвольной пары программ в заданной модели вычислений требуется выяснить, обладают ли эти программы одинаковым поведением. Уточняя понятия вычислительной модели, программы и ее поведения, мы получаем многочисленные вариации проблемы эквивалентности. Известно, что проблема эквивалентности программ неразрешима в тех случаях, когда модель вычислений является универсальной. В то же время, начиная с основополагающей работы Ю.И.Янова, удалось выделить обширные классы программ с разрешимой проблемой эквивалентности. В течение долгого времени основные усилия в этой области были сосредоточены на выявлении самого факта алгоритмической разрешимости эквивалентности программ. Подавляющее большинство полученных разрешающих процедур имели высокую сложность
и были мало пригодны для практического применения. Суть предложенного В.А.Захаровым подхода такова. Заданной вычислительной модели программ сопоставляется специальная полугруппа − критериальная система. С ее помощью для любой пары анализируемых программ можно построить систему переходов, описывающую всевозможные пары совместных вычислений этих программ. При этом для подтверждения эквивалентности программ необходимо и достаточно убедиться в том, что ни одна из особо выделенных опровергающих вершин не достижима из начального состояния. Оказывается также, что для проверки этого условия можно ограничиться анализом лишь некоторого начального фрагмента построенной системы переходов, размер которого полиномиально зависит от размеров исследуемых программ. В тех случаях, когда всякий начальный фрагмент системы переходов может быть построен эффективно, мы получаем удобный и быстрый алгоритм, разрешающий эквивалентность программ. При помощи указанного подхода удалось построить полиномиальные по сложности алгоритмы, разрешающие эквивалентность в отдельных классах пропозициональных операторных программ с перестановочными [12, 14, 15, 67] и частично-перестановочными [15, 16], [67] операторами, унарных рекурсивных программ [13], первопорядковых операторных программ [67]. В заключение авторы благодарят С.А. Фомина за помощь и многочисленные полезные замечания при написании этой статьи. Работа выполнена при поддержке РФФИ, проекты 99-01-00210, 99-0100211. Литература 1. Ахо А., Хопкрофт Дж., Ульман Дж. Построение и анализ вычислительных алгоритмов. М.: Мир, 1979. 2. Бухштабер В.М., Холодов А.Н. Группы формальных диффеоморфизмов суперпрямой, производящие функции для последовательностей полиномов и функциональные уравнения. Изв. АН СССР. Сер. Матем. 53(5) (1989) 944-970. 3. Бухштабер В.М., Холодов А.Н. Структуры БоасаБака на последовательностях полиномов. Функц. анализ. 23(4) (1989) 11-23. 4. Бэйтмен Г., Эрдейи А. Высшие трансцендентные функции. Т. 2. М.: Наука, 1974. 5. Бэйтмен Г., Эрдейи А. Высшие трансцендентные функции. Т. 3. М.: Наука, 1967. 6. Вентцель Е.С., Исследование операций. Задачи, принципы, методология, М., Наука, 1988. 7. Висков О.В. Операторная характеризация обобщенных полиномов Аппеля. ДАН СССР. 225 (1975) 749-752. 8. Гэри М., Джонсон Д.С. Вычислительные машины и труднорешаемые задачи, М.: Мир, 1982. 9. Журавлев Ю.И. О невозможности построения минимальных дизъюнктивных нормальных форм функций алгебры логики в одном классе алгоритмов, ДАН СССР, 1960, т. 132, N 3, С. 504-506.
147 10. Журавлев Ю.И. Локальные алгоритмы вычисления информации. Кибернетика. 1965, N 1, С. 12-19. 11. Журавлев Ю.И. Теоретико-множественные методы алгебры логики. Проблемы кибернетики. вып. 8, М.: Физматгиз, 1962, С. 5-44. 12. Захаров В.А. О проблеме эквивалентности пропозициональных программ над полугруппами, Kurosh Algebraic Conference'98, Abstracts of Talks, 1998, c.170-172. 13. Захаров В.А., Подловченко Р.И., Полиномиальный по сложности алгоритм, распознающий коммутативную эквивалентность схем программ, Доклады РАН, 1998, т.362, N 6. 14. Захаров В.А. Быстрые алгоритмы разрешения эквивалентности операторн ых программ на уравновешенных шкалах, Математические вопросы кибернетики, Физматлит, 1998, вып.7. 15. Захаров В.А. Быстрые алгоритмы разрешения эквивалентности пропозициональных операторных программ на упорядоченных полугрупповых шкалах, Вестник Московского Университета, сер.15, Вычислительная математика и кибернетика, 1999, N 2. 16. Захаров В.А., Спанопуло В.В. О взаимосвязи двух семантик параллельных вычислений, Программирование, РАН, 1997, N 5, c.36-48. 17. Захаров В.А., Царьков Д.В. Эффективные алгоритмы проверки выполнимости формул темпоральной логики CTL на модели и их применение для верификации параллельных программ, Программирование, РАН, 1998, N 5. 18. Кузюрин Н.Н. Асимптотически точные полиномиальные алгоритмы в целочисленном линейном программировании, Дискретная математика, 1989, т. 1, N 2, C. 78-85. 19. Кузюрин Н.Н. Метрические аспекты теории целочисленного линейного программирования, Дискретная математика , 1994, т. 4, N 6, C. 499-518. 20. Кузюрин Н.Н. Распределенное принятие решений, Сб. Методы комбинаторной оптимизации, М., ВЦ РАН, 1997, С. 30-36. 21. Кузюрин Н.Н. Оценки оптимумов задач ЦЛП типа покрытия, Дискретные модели и методы, вып. 2, М.: ВЦ РАН, 1996. Коммуникационно-эффективные 22. Кузюрин Н.Н. алгоритмы решения задач линейного и целочисленного программирования, Вопросы кибернетики. Приложения системного программирования, М., ВИНИТИ, 1998, вып. 4, С. 162-174. 23. Мартишин С.А. Алгоритм нахождения крайних точек множества в D-мерном евклидовом пространстве с использованием линейного программирования, Вопросы кибернетики. Приложения системного программирования, вып. 1, М.: ВИНИТИ, 1995. 24. Мартишин С.А. Динамический алгоритм вычисления некоторых характеристик ячеек диаграммы Вороного на плоскости с ограничениями, Вопросы кибернетики. Приложения системного программирования, вып. 3, М.:ВИНИТИ, 1997, С. 240-257. 25. Нестеров Ю.Е. Метод линейного программирования с трудоемкостью O(n3L) операций, Экономика и математические методы, 1988, т. 24, N 16, C. 174-176. 26. Схрейвер А. Теория линейного и целочисленного программирования (в двух томах), М.: Мир, 1991.
27. Фомин С.А. Исследование эффективности реализации нового приближенного алгоритма для задачи положительного линейного программирования, Вопросы кибернетики. Приложения системного программирования, М.: ВИНИТИ, вып. 4, 1998, С. 175-185. 28. Фрумкин М.А., Холодов А.Н. Об алгоритмах разложения данного полинома по последовательностям полиномов Боаса-Бака, Вопросы кибернетики. Приложения системного программирования, вып. 4, М.: ВИНИТИ, 1998, С. 144-161. 29. Хачиян Л.Г. Полиномиальный алгоритм в линейном программировании, ДАН СССР, 1979, т. 244, С. 1093-1096. 30. Шокуров А.В. Об эффективной реализации статистических программ на конвейерных ЭВМ, Вопросы кибернетики. Приложения системного программирования, вып. 4, М.: ВИНИТИ, 1998, С. 119-143. 31. Шокуров А.В., Захарова Н.И. Генерирование случайных последовательностей на векторноконвейерной ЭВМ, Вопросы кибернетики. Базовое программное обеспечение суперЭВМ, М.: ВИНИТИ, 1990, С. 59-78. 32. Шокуров А.В. Вычисление функций на векторноконвейерной ЭВМ, Кибернетика и вычислительная техника. вып.4, М.: Наука, 1988, C. 7-27. 33. Alizadeh F. Interior point methods in semidefinite programming with applications to combinatorial optimization, SIAM Journal Optimization, 1995, v. 5, N 1, 13-51. 34. Alon N., Spencer J.H. The probabilistic method. John Wiley and Sons inc., New York, 1992. 35. Asratian A.S., Kuzjurin N.N. Approximations of packing-covering integer programs via linear relaxations, Research Report 1998-18, Department of Mathematics, Lulea University of Technology. 36. Awerbuch B., Azar Y. Local optimization of global objectives: competitive distributed deadlock resolution and resourse allocation, 26th ACM STOC-94, 1994, 240-249. 37. Bartal Y., Byers J.W., Raz D. Global optimization using local information with applications to flow control, 38th IEEE FOCS-97, 1997, 303-312. 38. Boas R.P. and Buck R.C. Polynomial expansion of analytic functions. Berlin: Springer, 1958. 39. Chihara T.S. Ortogonal polynomials with Brenke type generating functions. Duke Math. J. 35(3) (1969) 505517. 40. Clarkson K.L. Las Vegas algorithm for linear programming when the dimension is small. Proceedings of Ann. 29th IEEE FOCS, 1988, pages 452-457. 41. Cormen T.H., Leiserson C.E., Rivest R.L. Introduction to Algorithms, The MIT Electrical Engineering and Computer Science Series, 1997. 42. Goodrich M.T., Communication-Efficient Parallel Sorting, Proc.30th ACM Symposium on Theory of Computing (STOC), 1996. 43. Hayman J.M., Lazar A.A., Pacifici G. Joint scheduling and admission control for ATS-based switching nodes, Proc. ACM SIGCOMM, 1992, 223-234. 44. Jabotinsky E. Analytic iteration. Trans. Amer. Math. Soc. 108 (1963) 457-477. 45. Karmarkar N. A new polynomial-time algorithm for linear programming, Combinatorica, 1984, v. 4, p. 373395.
148 46. Klee V., Minty G.J. How good is the simplex algorithm? Inequalities. III, Academic Press, New York, 1972, p. 159-175. 47. Kushilevitz E., Nisan N. Communication Complexity, Cambridge University Press, 189 pp., 1997. 48. Kuzjurin N.N., Shabanov L.V. A parallel algorithm for fixed-dimensional linear programming, Parallel Algorithms and Applications, 1995, v. 5, N 34, P. 17-24. 49. Kuzjurin N.N. On the difference between asymptotically good packings and coverings. – European J. Comb. 16 (1995) 35 – 40. 50. Kuzjurin N.N. Locally explicit constructions of Rodl's asymptotically good packings, Lecture Notes in Computer Science, 1998, v. 1450, Proc. MFCS-98, Brno, Czech Republic, August 1998, pp. 194-202. 51. Jan van Leeuwen, editor. Handbook of Theoretical Computer Science, vol. A. Algorithms and Complexity. Elsevier Science Publishers B.V. and The MIT Press, 1990. 52. Luby M., Nisan N. A parallel approximation algorithm for positive linear programming, Proc. 5th ACM-STOC, 1993, 448-457. 53. Motwani R., Raghavan P. Randomized Algorithms, Cambridge University Press, 1995. 54. Naor M., Shulman L.J., Srinivasan A, Splitters and nearoptimal derandomization, Proc. 36th Ann. IEEE FOCS, 1995, 182-191. 55. Papadimitriou C.H., Yannakakis M. Linear Programming Without the Matrix, Proc. 25th ACM STOC-93, 1993, 121-129. 56. Raghavan P., Tompson C.D. Randomized rounding: a technique for provably good algorithms and algorithmic proofs, Combinatorica, 37 (1987) 365-374. 57. Raghavan P. Probabilistic constructions of deterministic algorithms: approximating packing integer programs. J. Comput. and Syst. Sci., 1988, v. 37, N 4, pp. 130-143. 58. Rainville D.E. Special functions. Macmilan Co. N.-Y. 1960. 59. Roman S. The umbral calculus. N.-Y. A.P., 1984. 60. Roman S. The theory of the umbral calculus, I. J. Math. Anal. Appl.87 (1982) 58-115. 61. Shor P.W. Algorithms for quantum computations: discrete logarithm and factoring, Proceedings of the 35th IEEE FOCS, 1994, pp. 124-134. 62. Sparlinski I. Approximate constructions in finite fields, In Finite Fields and Applications, London Math. Soc., Lect. Notes Ser., v. 233, Cambridge Univ. Press, Cambridge, 1996, 313-332. 63. Sparlinski I. Finding irreducible and primitive polynomials, Appl. Algebra in Engin., Commun. and Computing, 4 (1993) 263-268. 64. Srinivasan A. Improved Approximation Guarantees for Packing and Covering Integer Programs, Proc. ACM Symposium on Theory of Computing, 1995, 268-276. 65. Srivastav A., Stangier P. Algorithmic ChernoffHoeffding inequalities in integer programming, Random Structures and Algorithms, 8, N 1 (1996) 27-58. 66. Plotkin S., Shmoys D.B., Tardos E. Fast approximation algorithms for fractional packings and covering problems, Proc. 32nd Annual Symp. IEEE Found. on Computer Sci., 1991, 495-504. 67. Zakharov V.A., Spanopulo V.V. To the Relationship between the Interleaving and Causal Models of Parallel Computations, Advances in Modal Logic'96, CSLI Publications, 1997, pp. 221-232. 68. Zakharov V.A. On the verification of PLTL formulae by means of monotone disjunctive normal forms, Lecture
Notes in Computer Science, Springer-Verlag, 1997, v.1234, p.419-429.