KOI WIN LATEX PS PDF |== > К списку публикаций To the list of publications
Опыт практической эксплуатации параллельных вычислительных систем показал, что одной из самых сложных проблем стала адаптация программного обеспечения под архитектуру конкретной ЭВМ. Появился целый спектр совершенно новых задач: нахождение потенциального параллелизма, преобразование структур данных под многоуровневую память, нахождение ``узких мест'' и ряд других. Очень часто для решения подобных задач пользуются только исходным текстом программы, проводят его анализ, пытаясь спрогнозировать поведение программы на этапе выполнения и на основании этого знания делают вывод о возможности целевой оптимизации. Проводимый анализ часто называют статическим анализом, поскольку никакой информации со стадии исполнения программы не используется.
Важным источником адаптируемых программных систем является огромный арсенал программного кода, накопленный за полвека использования последовательных ЭВМ. Одним из основных достоинств этих программ является их надежность, проверенная десятилетиями эксплуатации. К сожалению, попытки ускорить исполнение программы на суперкомьютере иногда наталкиваются на трудности, связанные с тем, что программный код оптимизирован под последовательную ЭВМ.
| subroutine S1(P,N) | subroutine S2(P,N) | subroutine S3(P,N) |
| dimension P(1) | dimension P(1) | dimension P(1) |
| dimension P17(N,N) | ||
| С Expanding P to P17 | ||
| ii = 1 | ||
| do i = 1, N | ||
| do j = 1, i | ||
| P17(j,i) = P(ii) | ||
| ii=ii+1 | ||
| end do | ||
| end do | ||
| ii = 1 | C ii = 1 | С Source text with P17 |
| do i = 1, N | do i = 1, N | do i = 1, N |
| do j = 1, i | do j = 1, i | do j = 1, i |
| P(ii) = 1/(i+j-1) | P(j+(i-1)*i/2) = 1/(i+j-1) | P17(j,i) = 1/(i+j-1) |
| ii=ii+1 | C ii=ii+1 | C ii=ii+1 |
| end do | end do | end do |
| end do | end do | end do |
| С Packing P17 to P | ||
| ii = 1 | ||
| do i = 1, N | ||
| do j = 1, i | ||
| P(ii) = P17(j,i) | ||
| ii=ii+1 | ||
| end do | ||
| end do | ||
| return | return | return |
| end | end | end |
Рассмотрим следующую ситуацию: для вычислительной задачи был составлен алгоритм, в котором существенную роль играют действия с двух- и более мерными массивами; при программной реализации алгоритма, чтобы получить более эффективный код, многомерные массивы были вытянуты в векторы; при этом выражения для индексов массивов усложнились и стали, вообще говоря, нелинейно зависеть от параметров циклов и внешних (по отношению к данному фрагменту программы) переменных. Для того, чтобы при вычислении индексных выражений не использовать операции умножения, вводят индуктивные переменные, которые изменяются в циклической конструкции только посредством прибавлений константы и присваиваний таким образом, чтобы на соответствующей итерации они совпадали с нужным индексным выражением.
Другая ситуация связана с использованием структуры данных, которая формально не присутствует в языке, например треугольной матрицы или многомерного массива, координатные размерности которого зависят от внешних переменных. В этом случае многомерные массивы также вытягиваются в векторы и происходит преобразование программы, аналогичное только что изложенному.
В результате программа теряет читаемость и те возможности для ускорения, которые присутствовали в исходном алгоритме. Примером такой программы может послужить подпрограмма S1, изображенная на рисунке 1. Мы видим, что индексное выражение массива P равно индуктивной переменной ii, значение которой каким-то образом зависит от параметров цикла. В большинстве случаев (и, в частности, здесь) можно предъявить индексную функцию, которая выражает значение переменной ii на конкретной итерации цикла через параметры объемлющих циклов и внешние по отношению к данному фрагменту программы переменные. В данном случае ii=i(i-1)/2+j. Поиск индексной функции в общем случае представляет отдельную сложную проблему, которая не будет затронута в рамках данной работы. В дальнейшем будем считать, что при исследовании текста программы каким-то образом удалось найти индексные функции и, подставив их вместо индексных переменных, получить, вообще говоря, нелинейное индексное выражение, зависящее только от параметров объемлющих циклов и внешних переменных. Проделав такую операцию над подпрограммой S1, получаем подпрограмму S2.
Мы рассматриваем программу из класса, которому, в частности, принадлежит S2. Нам недоступно описание исходного алгоритма, который она реализует. Наши возможности ограничиваются только формальным анализом текста программы. Логично предположить, что мы оказались именно в той ситуации, которую описали выше и нелинейность индексных выражений вызвана вытягиванием многомерного массива в вектор. Наша задача состоит в том, чтобы восстановить исходную ``естественную'' запись программы.
В этой статье исследуются условия, при выполнении которых последняя проблема разрешима в случае, когда ``упаковывается'' треугольная матрица. Мы найдем некоторые естественные достаточные условия того, что линейные индексные выражения могут быть восстановлены исходя только из нелинейного индексного выражения. Оказывается, в общем случае возможно бесконечное число таких восстановлений. Для выделения из этих многих вариантов ``настоящего'' требуется использовать информацию о структуре объемлющих циклов. Будут найдены достаточные условия конечности числа вариантов восстановления. Самым удивительным результатом работы является теорема 7, которая говорит, что если индексное выражение зависит только от параметров циклов и в пространстве итераций существует вершина, положение которой не зависит от внешних параметров, то существует не более одного варианта восстановления линейных индексных выражений. Например, подпрограмма S2 удовлетворяет условию этой теоремы.
Пользуясь техникой, изложенной в статье, можно найти этот единственный пригодный вариант восстановленных линейных индексных выражений в подпрограмме S2. Проиллюстрируем теперь способ представления исходной записи алгоритма. Преобразуем массив P в полноразмерный массив P17, который состоит из нижнего треугольника с диагональю, содержащего элементы P, и верхнего треугольника без диагонали, содержащего неиспользуемые элементы. Таким образом, получаем процедуру S3, которая эквивалентна исходной в смысле результатов работы. Индексные выражения второго гнезда циклов, который выполняет вычисления, а, следовательно, наиболее интересен, принимают стандартную линейную форму. Появляется наглядность: становится ясно, что подпрограмма S3 заполняет упакованный треугольный массив P элементами известной матрицы Гильберта порядка N.
Единственный неприятный момент состоит в том, что подпрограмма S3 запрашивает в три раза больше памяти, чем необходимо: вводится новый массив удвоенного размера, но остается и старый. Это результат чересчур прямолинейного восстановления естественной формы записи исходного алгоритма. Если, например, расширить семантику языка Фортран и ввести новый тип ``треугольный массив'', то вообще никакой дополнительной памяти не потребуется (но зато потребуется изменить компилятор). Проблему памяти можно решать другими методами: самое главное, что фрагмент программы приобрел естественный вид и возможен адекватный статический анализ этого фрагмента.
Данная работа примыкает к задаче отображения проблем вычислительной математики на архитектуру вычислительных систем, которая рассматривалась в книгах [1] и [2]. Проблематика статьи возникла из желания расширить класс программ, для которых возможен эффективный статический анализ.
Наиболее распространенным языком программирования для суперЭВМ является Фортран. Согласно установившейся традиции, мы будем изучать фрагменты программ на языке Фортран, хотя все полученные результаты, с несущественными изменениями формулировок, применимы к любому процедурному языку.
Будем говорить, что выражение, содержащееся в операторе S фрагмента, имеет стандартную линейную форму, если оно имеет вид: f1 x1+╪+ fn xn+f0+fn+1 z1+╪+fn+p zp, где x1, ..., xn - параметры объемлющих оператор S циклов, предположим, что их имеется ровно n; f0, ..., fn+p н Z; z1, ..., zp - целочисленные переменные, не изменяемые в данном фрагменте (такие переменные будем называть внешними для данного фрагмента), предположим, что их имеется ровно p. Все операторы, осуществляющие выбор последующего действия в зависимости от истинности некоторого условия, будем называть альтернативными операторами. Тело цикла при каком-то одном значении управляющего параметра назовем итерацией цикла (например, заголовок ``DO 1 i=1,N'' задает N итераций). Будем предполагать, что проверка значения управляющего параметра происходит перед выполнением итерации (так, как принято в Фортране-77).
Определение 1. Фрагмент программы принадлежит линейному классу при выполнении следующих условий:
1) он состоит только из операторов присваивания, операторов цикла DO, альтернативных операторов (IF и пр.) и операторов безусловного перехода, причем все циклы фрагмента заданы только операторами DO;
2) все индексные выражения всех обращений к массивам, условия альтернативных операторов, начальные и конечные значения параметров всех циклов имеют стандартную линейную форму;
3) шаг изменения параметров DO-циклов равен единице. Линейный класс программ занимает среди программного обеспечения примерно такое же место, как матрицы в конечномерном анализе, линейные дифференциальные уравнения в теории обыкновенных дифференциальных уравнений, численные методы линейной алгебры в вычислительной математике и т.п. В [1] показано, как для конкретного фрагмента, принадлежащего линейному классу, можно эффективно построить исчерпывающее описание его графа алгоритма с помощью системы функций, линейных как по параметрам цикла, так и по внешним переменным. В [3] доказан фундаментальный факт: для любой программы линейного класса набор таких функций конечен и не зависит от значений внешних переменных.
Будем рассматривать проблему преобразования к линейному классу фрагментов, для которых частично не выполнено условие 2. Этот класс будем называть Virtual Dimension или, сокращенно, VD.
Определение 2. Фрагмент программы принадлежит классу VD, если он удовлетворяет условиям 1), 3), и 2), за тем исключением, что индексные выражения некоторых обращений к массивам имеют вид многочлена от параметров объемлющих циклов и внешних переменных.
Не приходится рассчитывать, что любая программа имеет вид, который требуется в последнем определении, но подавляющее большинство программ можно привести к нужному виду, причем привести, разумеется, с гарантией сохранения результатов вычислений. За более подробной информацией читатель может обратиться к статье [4].
Поскольку различие линейным и VD классами состоит только в форме обращений к массивам, нас прежде всего должна интересовать структура конкретного обращения к массиву. Рассмотрим оператор S нашего фрагмента, в котором находится обращение O к массиву, название которого обозначим через P. Вследствие определения фрагментов класса VD, при фиксированном z множество всех допустимых комбинаций параметров циклов x =(x1, ╪, xn)T принимает значения из многогранника WI(z), который будем называть пространством итераций. Из определения класса VD вытекает, что многогранник WI(z) описывается с помощью параметризованной системы линейных неравенств Ax ё b(z), где каждая компонента b(z) имеет стандартную линейную форму. Будем говорить, что выражение для индекса массива P по k-той координате имеет стандартную полиномиальную форму, если оно записывается в виде многочлена g(x,z) многих переменных над полем рациональных чисел. Предположим, что для любого z н W множество WI(z) непусто и ограничено.
Определение 3.
Будем называть адресным обращением набор
| (2.1) |
|
Восстановленные линейные индексы многомерного массива обязаны удовлетворять некоторым линейным неравенствам, которые должны быть выполнены при всех допустимых комбинациях параметров объемлющих циклов. Для проверки неравенств необходимо находить минимум линейного функционала на пространстве итераций, которое зависит от внешних переменных. В этом пункте мы развиваем математический аппарат, необходимый для решения этой задачи.
Построим алгоритм нахождения параметрического минимума стандартной
линейной формы f1 x1+╪+ fn xn+f0+fn+1 z1+╪+fn+p zp=(fx,x)+(fz,z)+f0,
где (·,·) обозначает скалярное произведение в пространствах
одинаковой размерности, fx=(f1,╪,fn)T,
fz=(fn+1,╪,fn+p)T, индекс T обозначает
транспонирование:
|
| (2.2) |
Вектор x*(z) является решением, если при фиксированном z для любых допустимых x (c,x*(z)) ё (c,x). Значением задачи PL называется функция f(z)=(c,x*(z)).
Рассмотрим двойственную к (2.2) задачу линейного
программирования
| (2.3) |
Вектор y*(z) является решением, если при фиксированном z для любых допустимых y: (b(z),y*(z)) Ё (b(z),y). Значением задачи DL(z,W) называется функция (b(z),y*(z)).
Из непустоты и ограниченности M(A,b(z)), следует, что значение
DR(z,W) существует и совпадает со значением
PR(z,W) (см. [6]).
Многогранник ограничений задачи DR(z,W) также непуст и
ограничен, а, следовательно, имеет конечное число w вершин
y1, ..., yw. Поскольку значение задачи
DR(z,W) совпадает со значением функционала
(b(z),y) в некоторой вершине допустимого множества
задачи DR(z,W), справедлива формула:
| (2.4) |
Лемма 1
Для полиэдра W л Rp такого, что
"z н W допустимое множество M(A,b(z))
непусто и ограничено, существует конечное, не зависящее от значений
внешних переменных, разбиение на полиэдры, такое что на каждом из
них координаты вершин M(A,b(z)) являются линейными
формами с рациональными коэффициентами от z.
|
Двойственная задача имеет вид
|
Базисом называется всякая невырожденная матрица, составленная из n строк матрицы A. Пусть номера строк задаются множеством v. Допустимым базисом задачи DRi называется такая матрица B=Av, что (BT)-1c ё 0. Рассмотрим точку x(z)=B-1bv(z). Обозначим [`v]={1, ..., m}\v, N=A[`v]. Ввиду [7,Глава 2, 1.6, теорема 3] точка x(z) является вершиной допустимого множества задачи PRi тогда и только тогда, когда выполнена система неравенств Nx(z) ё b[`v](z) или A[`v](Av)-1bv(z) ё b[`v](z). Последняя система определяет полиэдр в пространстве внешних переменных, для которого координаты вершины x(z) линейно зависят от z. Перебрав все допустимые базисы для задачи DRi и решив соответствующие системы, мы найдем, вообще говоря, неоднородные кусочно-линейные не всюду определенные функции, которые задают координаты вершин полиэдра M(A,b(z)). Эти вершины лежат на грани M(A,b(z)), которая лежит в плоскости (c,x)=-bi(z) (или A{i}x =bi(z)); число кусков линейности каждой координатной функции конечно. Носитель каждой функции является объединением конечного числа полиэдров.
Аналогичное построение верно для i=[`1,m]. Утверждение леммы вытекает из конечности числа носителей функций и конечности числа вершин. q.e.d.
Значение ``непрерывной'' задачи PR(b(z), W) при целом z всегда меньше либо равно значения ``целой'' задачи PZ(b(z), W). Они совпадают, если многогранник ограничений Ax ё b(z) является целочисленным, то есть все его вершины при целых z имеют только целочисленные координаты. Такие полиэдры возникли в связи с так называемой ``транспортной задачей''. Еще основателями теории линейного программирования, был описан класс таких матриц A, что многогранник ограничений M(A,b) является целочисленным при любом целом b.
Заметим, что наш класс матриц включается в этот. Действительно, вектор b(z) при целочисленном z является целочисленным, но зависит не от m параметров, а от p, причем совсем не обязательно p=m. На практике p << m, чаще всего p=1, реже p=2. Поэтому теоремы, рассмотренные ниже, дают достаточные условия на целочисленность M(A,b(z)).
Определение 4. Назовем целочисленную матрицу A абсолютно унимодулярной, если все ее миноры равны либо 0, либо ╠1.
Теорема 1
Множество M(A,b) целочисленно при любом
целочисленном векторе b тогда и только тогда, когда матрица
A абсолютно унимодулярна.
Теорема 2
Пусть A - целочисленная матрица из {╠1, 0} с не
более чем двумя ненулевыми элементами в каждом столбце. Для того
чтобы A была абсолютно унимодулярной, необходимо и достаточно,
чтобы строки е\" можно было разбить на два класса,
обладающих следующими свойствами.
1) Если строки i и k принадлежат одному и тому же классу и
для некоторого j имеем aij ╧ 0, akj ╧ 0, то
aij=-akj.
2) Если строки i и k принадлежат разным классам, и для
некоторого j имеем aij ╧ 0, akj ╧ 0, то
aij=akj.
| (3.1) |
| (3.2) |
|
|
| Таблица |
|
Наша общая задача восстановления линейных индексных выражений в данном случае состоит в том, чтобы выделить множества Wk л W, на которых можно задать стандартные линейные формы Lk(x,z) и Rk(x,z), удовлетворяющие следующим условиям
а) (Lk(x,z),Rk(x,z)) н At для любого x н M(A,b(z)),
б) функция, соответствующая At, от Lk(x,z) и Rk(x,z) равна g(x,z).
Поскольку мы хотим найти представление g(x,z) в виде композиции специального многочлена второй степени и стандартных линейных форм L и R, то сразу возникает необходимое ограничение на степень g: она не должна превосходить 2.
Посредством линейных замен пары из A3 и A4 переводятся в
пары из A1 и A2 соответственно. Поэтому
для g(x,z) должно быть справедливо одно из
представлений:
|
Классификация. Знак коэффициента при квадрате любой переменной вектора x в многочлене g(x,z) является инвариантом, однозначно определяющим выбор представления:
1) если коэффициент положителен, то g=F(·,·),
2) если коэффициент отрицателен, то g=G(·,·).
Если у квадратов разных переменных x различны знаки, то восстановить линейные индексные выражения нельзя. Если квадраты переменных x отсутствуют, то возможны два случая.
Случай 1. g(x,z) является линейной неоднородной функцией x - тогда выбор представления следует согласовывать с другими обращениями к этому массиву; при этом возможны два варианта:
a) g(x,z)=F(a(z),R(x,z)), 1 ё R(x,z) ё a(z), или g(x,z)=G(a(z),R(x,z)), 1 ё R(x,z) ё q-a(z)+1, здесь L(x,z) равно линейной неоднородной функции a(z), это означает, что программа обращается непосредственно к строке a(z) треугольной матрицы;
б) не существует такой константы a, чтобы было выполнено одно из условий предыдущего пункта, это означает, что массив проходится нерегулярно - циклическая конструкция не согласована со структурой многомерного массива; можно попытаться согласовать данное адресное обращение с другими к этому же массиву при помощи расщепления циклов.
Случай 2. В противном случае нельзя представить g(x,z) в виде композиции одной из функций F или G и линейных форм (таким образом, адресные обращения вроде T(I*J)) исключены).
Рассмотрим технику восстановления линейных индексных выражений для адресного обращения с функцией F. Аналогичную технику можно применить для случая с G.
|
Лемма 2
Квадратичная форма Q[y] ╧ 0 разлагается
в квадрат линейного функционала от
y тогда и только тогда, когда она симметрична с
неотрицательными элементами на диагонали и каждые два ненулевых
столбца матрицы Q пропорциональны.
Вычислим символьно:
|
| do i=p,p+q |
| do j=r,r+s |
| A(j+i*(i-1)/2)=i+j |
| enddo |
| enddo |
Существует ли фрагмент программы класса VD, который имеет бесконечно много вариантов восстановления линейных индексных выражений (для различных внешних параметров)? Как ни странно, такой фрагмент действительно существует. Его код приведен на рисунке 2.
Исследуем этот фрагмент в предположении, что нам заведомо ничего не
известно про параметры p, q, r и s.
В первую очередь заметим, что для адресации используется
специальная функция F(·,·).
С помощью пункта 3.3 выделяем
L0=[L\tilde]
=i, R0=[R\tilde]
=j. На первый взгляд,
в программе обрабатывается
прямоугольник размера (q+1)×(s+1). Тем более удивительно, что
это не единственный вариант обработки упакованного треугольного
массива.
Зададим
|
|
|
|
Может показаться, что пример довольно сомнителен: в реальной программе значения p, q, r и s определены заранее и к началу исполнения фрагмента они известны, а следовательно, такого изобилия вариантов может и не быть. Поэтому еще раз подчеркнем, что мы рассматриваем фрагмент отдельно от всей программы и про p, q, r и s заведомо ничего не известно. Такая постановка задачи вполне соответствует духу статического анализа: определить структуру фрагмента, и лишь затем согласовывать ее с остальными структурами. Разобранный пример демонстрирует, что множество программ, которые можно задать с помощью процедурного языка, значительно шире множества реальных программ. Редкий разработчик программного обеспечения закладывает в текст программы бесконечно большое количество вариантов ее поведения в зависимости от значений внешних параметров. Поэтому на практике такое разнообразие не встречается, а, следовательно, встает задача выделения класса таких фрагментов, для которых существует лишь конечное число вариантов их восстановления. Теоремы следующего пункта дают возможность выделить такой класс.
Рассмотрим адресное обращение (2.1). Предположим, что, воспользовавшись техникой пункта 3.3, нам удалось выделить стандартные линейные формы L0 и R0, такие, что F(L0,R0)=g (вообще говоря, L0 известно с точностью до знака; предположим, что знак фиксирован). Исходное индексное выражение L отличается от L0 на некоторую неизвестную константу. Обозначим Lk=L0+k. Линейная форма Rk определяется из условия F(Lk,Rk)=g. Поэтому все возможные пары (Lk,Rk) задаются равенствами Lk=L0+k, Rk = R0-kL0-k(k-1)/2.
Лемма 3
Для фиксированного
z н W стандартные линейные формы Lk(x,z) и
Rk(x,z) являются корректными индексными выражениями в
треугольном массиве тогда и только тогда, когда
"x н M(A,b(z)): 1 ё Rk(x,z) ё Lk(x,z). (3.3)
|
Лемма 4 Для фиксированного z н W
условие (3.3) выполнено тогда и только тогда, когда
1 ё Rkmin(z) и (Lk-Rk)min(z) Ё 0. (3.4)
|
Лемма 5
Справедливы следующие утверждения.
1) Mk ограничиваются прямыми
Rk(L)=kL+k(k-1)/2 и Rk+1(L)=(k+1)L+k(k+1)/2:
Mk={Rk(L) Ё 1}г{Rk+1(L) ё 0}.
2) Каждое Mk ограничивается углом, вершина которого лежит на параболе
P(L)=1-L(L-1)/2 и имеет координаты (1-k,1-k(k-1)/2)T.
3) Для любых j ╧ k множества Mj и Mk не пересекаются.
4) Рассмотрим ограниченное множество M на плоскости LR. Множество
M пересекается лишь с конечным числом Mk или не пересекается
ни с одним из Mk.
5) Зададим в плоскости LR множество U с помощью прямых
U1(L)=U11L+U12 и U2(L)=U21L+U22,
U11 > U21: U={(L,R)T: R ё U11L+U12, R Ё U21L+U22 }. Множество U пересекается лишь с конечным числом
Mk.
Лемма 6
Точка z н Wk тогда и только тогда, когда для
всех вершин i=[`1,v] полиэдра M(A,b(z)) выполнено
Xi(z) н Mk.
Лемма 7
Для любых целых чисел j и k таких, что j ╧ k,
WjгWk=ф.
Пользуясь алгоритмами параметрического линейного программирования пункта 2.3, можно разбить W на непересекающиеся многогранники Wk так, что z н Wk тогда и только тогда, когда для z и k выполнено (3.3). Для z н Wk искомыми индексными выражениями являются Lk и Rk. Адресное обращение (2.1) имеет конечное число вариантов восстановления линейных индексных выражений тогда и только тогда, когда лишь конечное число множеств Wk целочисленно не пусты. Достаточным признаком целочисленной непустоты Wk является непустота Wk. Следующие теоремы дают достаточные признаки непустоты лишь конечного числа Wk. Все эти теоремы имеют силу для адресных обращений с матрицей A, которая не является абсолютно унимодулярной. Унимодулярность A требуется только при реализации алгоритма, описанного в пункте 2.3.
Теорема 3
Если множество W внешних параметров ограничено, то не более чем
конечное число множеств Wk непусто.
Определение 6.Назовем лучом Lz0, v множество Lz0, v={z н Rp:z =z0+av,a Ё 0}. Будем называть точку z0 основанием луча, а вектор v - направлением луча. Из каждого основания луч может выходить по нескольким направлениям. Будем обозначать через V(z0) множество направлений всех лучей, которые выходят из основания z0.
Лемма 8
Произвольный неограниченный полиэдр можно представить в виде
объединения лучей так, что
множество Wz оснований лучей ограничено, а каждое направление
луча из множества V(z0) имеет единичную норму:
W=
х
z0, v
Lz0,v, z0 н Wz: ||z0|| < b,
v н V(z0), ||v||=1 .
(3.5)
Теорема 4
Пусть существует такая вершина i полиэдра M(A,b(z)),
что для всех Lz0,v в
объединении (3.5)
1) (xx,Bi(v))+(xz,v) Ё e > 0,
2) L0(xi(z0),z0) Ё 1.
Тогда не более чем конечное число множеств Wk непусто.
Доказательство
В условиях теоремы лучу (xi(Lz0,v),Lz0,v) сопоставляется луч
L[(z)\tilde]0,[(v)\tilde] по правилу
| (3.6) |
| (3.7) |
| (3.8) |
Теорема 5 Пусть существует такая вершина i, что
для всех лучей Lz0,v в
объединении (3.5)
1) (xx,Bi(v))+(xz,v)=0,
2) (cx,Bi(v))+(cz,v)=0.
Тогда не более чем конечное число множеств Wk непусты.
Теорема 6
Пусть выполнены условия 1) и 2) предыдущей теоремы. Если в дополнение
к ним выполнено условие
3) для любого z0 н Wz: L0(xi(z0),z0) = U1,
R0(xi(z0),z0) = U2, где U1 и U2 - некоторые
константы,
то не более чем одна из областей {Wk}
непуста.
Теорема 7 [принцип неподвижной точки пространства итераций]
Пусть выполнены следующие условия.
1) Хотя бы одна вершина M(A,b(z)) имеет фиксированные координаты, не
зависящие от внешних параметров.
2) xz=0 и cz=0; это означает, что L0 и R0 зависят
только от параметров объемлющих циклов и не зависят от внешних
переменных.
Тогда не более чем одна из областей {Wk}k=-╔╔
непуста.
Замечательная особенность последней теоремы состоит в том, что ее условия можно легко проверить исходя сразу из текста программы, не обращаясь к довольно сложному построению леммы 1. Есть основания полагать, что условия теоремы 7 выполнены для подавляющего большинства реальных программ класса VD, обрабатывающих упакованный треугольный массив.
1) Нахождение размера используемой части массива. Мы можем решать эту задачу, используя технику пункта 2.3 для нахождения максимума Lk(x,z).
2) Согласование с линейными формами. Пусть мы восстановили какое-то адресное обращение к массиву P с нелинейной g(x,z)=F(L(x,z),R(x,z)). Может возникнуть такая ситуация, что в другом адресном обращении к массиву P функция g1(x,z) имеет стандартную линейную форму. Логично предположить, что g1 имеет представление g1=F(a,R1), где a Ё 1. Это один из случаев, упоминавшихся в классификации пункта 3.2. В этой ситуации справедливы все теоремы пункта 3.5 с L0=1, R0=g1.
1. F=J(J-1)/2+K, K н [`(1,J-1)], J н [`2,N], W ={[`(2,╔)]}. L0 =J, R0 =K. У многогранника ограничений есть фиксированная вершина (1,2), индексы L0 и R0 не зависят от внешних параметров. Из теоремы 5 следует, что можно предъявить не более одной непустой области Wk. Kmin=1, (J-K)min=1 (при J=2, K=1), W0=W ={[`(2,╔)]}, следовательно, исходные индексы L=J и R=K.
2. F=K(K-1)/2+1, K н [`(1,J-1)], J н [`2,N], W ={[`(2,╔)]}. L0 =K, R0 =1. W0=W ={[`(2,╔)]}, исходные индексы: L=K и R=1.
3. F=J(J-1)/2+1. Аналогично предыдущему: L=J, R=1, W0=W.
4. F=K(K-1)/2+K, K н [`(1,J-1)], J н [`2,N], W ={[`(2,╔)]}. L0 =K, R0 =K. Результат: L=K, R=K, W0=W.
5. F=J(J-1)/2+K. Все дословно совпадает с шагом 1.
6. F=J(J-1)/2+J. J н [`1,N], W ={[`(1,╔)]}. L0 =J, R0 =J. W0=W ={[`(1,╔)]}, исходные индексы: L=J и R=J.
7. F=J(J-1)/2+J. Совпадает с шагом 6.
Теперь можно воспользоваться методом, предложенным во введении, для того, чтобы свести фрагмент к линейному классу.
Автор признателен Вл.В. Воеводину за постановку задачи, критику и внимание к работе. Совместные дискуссии с В.В. Воеводиным оказались весьма плодотворными и помогли придать результатам законченную форму. Несколько существенных замечаний сделал А.В. Фролов. Автор благодарен П.В. Харитонову за то, что он внимательно прочитал окончательный вариант и предложил ряд поправок.