Выше предложен алгоритм компоновки "длинных" командных слов
внутри линейного участка программы для
Очевидно, что для разных задач различна и актуальность механизмов ветвления. Существуют задачи, для которых этот механизм является основным средством решения. По-видимому, такие задачи целесообразно выбрать в качестве тестовых для оценки эффективности ветвления.
В теории алгоритмов на задачах сортировки принято оценивать возможность
снижения
Понятие O(n log2n),
где n — длина массива.
Однако выше речь идет о сложности алгоритма, а не о его реализации на компьютере. Компьютер, в результате слабой "профпригодности", может внести значительные коррективы сложности в худшую сторону.
Конечно, не всегда в этом случае виноват компьютер. При расчете сложности зачастую не учитываются объективно существующие затраты на организацию вычислительного процесса. Например, древовидная (графовая) структура требует значительных вычислительных затрат на обслуживание. Человек, производя сортировку "вручную", на неформальном уровне с легкостью производит логические действия, которые весьма трудоемки для компьютера.
Таким образом, необходимо:
В то же время, составляя планы программ сортировки, будем высказывать предположения или рекомендации относительно возможностей системы команд процессора.
Обобщенная программистская модель процессора EPIC-архитектуры
Под программистской моделью понимают то, что "видит"
программист (транслятор) в вычислительной системе и что достаточно для написания "хорошей"
программы. Ранее это называлось "
Так как нас интересует программа в виде расписания работы исполнительных
устройств (ИУ) арифметическо-логического устройства (АЛУ), будем составлять
планы компоновки таких расписаний, ориентируясь на
Для данной задачи достаточно рассматривать два логических ИУ. Пусть также используются два ИУ обмена информацией. Для оценки принципиальных возможностей оптимального программирования указанные параметры АЛУ несущественны.
Предположим, что все ИУ конвейерные, т.е. известно количество тактов счета
результатов. Существуют
Предикатные (логические) вычисления выполняются с помощью адресуемой памяти
(файла) предикатов
Предполагается аппаратная поддержка циклов, основанная на автоматическом переиспользовании (переименовании) регистров и исключающая остановки конвейера выполнения команд.
Целью сортировки является переформирование массива данных в порядке их невозрастания.
Данный метод заключается в том, что исходный массив условно делится на две части: уже отсортированную и еще не отсортированную. Первоначально отсортированная часть содержит лишь один, первый, элемент массива. Затем на каждом шаге первый элемент неотсортированной части вставляется в отсортированную часть на свое место с учетом упорядоченности.
Пусть задан массив a[1...12] = {6, 2, 4, 3, 4, 7, 10, 9, 5, 8, 0, 1}.
В табл. 8.1 отражен процесс сортировки по шагам, где курсивом выделена
упорядоченная часть массива.
Известны [10] оценки общего числа Cср
сравнений и Mпер пересылок:
$$C_{ср} = (n{}^2 + n - 2)/4$$,
$$M_{пер} = (n{}^2 + n - 2)/4$$,
что подтверждает оценку $$O(n{}^2 )$$.
| Исходный массив | 6 | 2 | 4 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Шаг 1 | 2 | 6 | 4 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
| Шаг 2 | 2 | 4 | 6 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
| Шаг 3 | 2 | 3 | 4 | 6 | 4 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
| Шаг 4 | 2 | 3 | 4 | 4 | 6 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
| Шаг 5 | 2 | 3 | 4 | 4 | 6 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
| Шаг 6 | 2 | 3 | 4 | 4 | 6 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
| Шаг 7 | 2 | 3 | 4 | 4 | 6 | 7 | 9 | 10 | 5 | 8 | 0 | 1 |
| Шаг 8 | 2 | 3 | 4 | 4 | 5 | 6 | 7 | 9 | 10 | 8 | 0 | 1 |
| Шаг 9 | 2 | 3 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 0 | 1 |
| Шаг 10 | 0 | 2 | 3 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 1 |
| Шаг 11 | 0 | 1 | 2 | 3 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Однако, пытаясь запрограммировать этот метод для параллельного АЛУ, мы сталкиваемся с преобладанием операций, выполняемых над элементами массива строго последовательно:
Метод явно нуждается в модификации, что при наличии других, ниже рассматриваемых, методов сортировки вряд ли целесообразно.
Общий принцип алгоритма:
n — 1 элементов, n — 2 элементов и т.д.
и меняется местами с первым элементом оставшейся части массива. Процесс
продолжается до тех пор, пока справа не останется один, самый большой элемент
исходного массива.Сложность алгоритма составляет $$O(n{}^2 )$$.
В табл. 8.2 показана по шагам сортировка того же массива. Курсивом выделены меняющиеся на каждом шаге местами первый и минимальный элементы неупорядоченной части массива.
Основная процедура, многократно применяемая в алгоритме — процедура нахождения минимального элемента среди уменьшающегося множества элементов.
Рассмотрим эту процедуру отдельно. В ней реализуется операция преобразования
вектора (массива) в скаляр, что также соответствует сложению или умножению всех
элементов массива. Эта операция является составной частью ]log2n[t, где t — время элементарной,
образующей операции (сравнения и возможной пересылки).
При использовании небольшого числа ИУ возможна их практически полная
загрузка на всем протяжении счета при наличии
| Исходный массив | 6 | 2 | 4 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Шаг 1 | 0 | 2 | 4 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 6 | 1 |
| Шаг 2 | 0 | 1 | 4 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 6 | 2 |
| Шаг 3 | 0 | 1 | 2 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 6 | 4 |
| Шаг 4 | 0 | 1 | 2 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 6 | 4 |
| Шаг 5 | 0 | 1 | 2 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 6 | 7 |
| Шаг 6 | 0 | 1 | 2 | 3 | 4 | 4 | 10 | 9 | 5 | 8 | 6 | 7 |
| Шаг 7 | 0 | 1 | 2 | 3 | 4 | 4 | 5 | 9 | 10 | 8 | 6 | 7 |
| Шаг 8 | 0 | 1 | 2 | 3 | 4 | 4 | 5 | 6 | 10 | 8 | 9 | 7 |
| Шаг 9 | 0 | 1 | 2 | 3 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| Шаг 10 | 0 | 1 | 2 | 3 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Представим схему счета "пирамидой" при нахождении минимального
элемента массива, на основе которой составим план программы для процессора n-1
элементами — промежуточными результатами анализа, а также (последний элемент) результатом поиска.
Для схемы счета "пирамидой" не принципиальна четность или
степень "двойки" значения n. На рис. 8.1 представлена схема
для n = 7.
(рис 8.1) Схема счёта "пирамидой"
Стрелки указывают на направление движения информации, $$\alpha _{1}$$ — $$\alpha _{6}$$ — значения предикатов — результатов попарного сравнения элементов.
Рисунок иллюстрирует простой цикл сравнения и пересылок меньших элементов. Единственным условием правильного выполнения операции является, как говорилось ранее, синхронизация, исключающая использование результата сравнения до окончания его формирования. При длине массива, значительно превышающей количество ИУ, эффективен механизм ожидания рассчитываемого результата, т.е. задержки выполнения команд при попытке считывания до записи. Задержки начнутся только на последнем этапе выполнения "пирамиды".
Однако отметим преимущества принудительного программного решения проблемы
синхронизации с помощью команды закрытия адресов по считыванию до окончания
записи по этим адресам. Такая команда позволяет предварительно закрыть адреса
данных an+1 - a2n-1. Их открытие при записи в ходе
выполнения программы обеспечивает правильное выполнение "пирамиды" во времени.
План программы выполнения данной процедуры представлен на рис. 8.2. Иллюстрируется "развернутый" цикл, где ромбами обозначены операции сравнения $$\alpha _{i} = a_{i} < a_{i+1}$$. Пересылки помечены предикатами или их отрицаниями, в соответствии со значениями которых они производятся. Считаем, что значение предиката может быть использовано через два такта, что определяет взаимное смещение пересылок и сравнений при формировании "длинных" командных слов. При формировании программы необходимо учесть организацию цикла, индексацию и т.д. Однако важно отметить, что все ветвление в данном проекте программы выполнено без остановок конвейера.
(рис 8.2) План программы счёта "пирамидой"
Тогда очевиден план программы сортировки с помощью прямого выбора. Процедура нахождения минимального элемента выполняется в цикле над уменьшающейся на единицу длиной массива. Найденный элемент меняется местами с первым элементом этого массива. Очевидно, в этом случае условный переход не используется.
Алгоритм этой сортировки заключается в последовательном сравнении и смене мест (если необходимо) пар соседних элементов массива. Процесс продолжается до тех пор, пока обмены не прекратятся. Сложность алгоритма также составляет $$O(n{}^2 )$$.
Легко видеть, что последовательный учет результатов предыдущего сравнения (последовательное всплытие "пузырьков") не допускает распараллеливания. Алгоритм нуждается в модификации.
Для эффективного распараллеливания на процессоре
Для этого при каждом обзоре текущее (частично упорядоченное) множество элементов разбивается на пары. При первом (нечетном) обзоре первая пара включает первый элемент массива. При втором (четном) обзоре группирование начинается со второго элемента и т.д. Внутри пар элементы упорядочиваются, при необходимости меняясь местами так, чтобы слева стоял меньший элемент. Наличие обменов при каждом просмотре фиксируется. Их прекращение свидетельствует об окончании сортировки массива.
Ниже по шагам (обзорам) отражена сортировка ранее рассмотренного
массива. Формируемые на каждом шаге пары элементов выделены. При четном n
нечетные шаги сортировки требуют анализа k = n/2 пар элементов, четные шаги
требуют анализа k = (n/2) - 1. При нечетном n k = [n/2] пар
элементов.
План программы (внутренний цикл развернут) представлен на рис. 8.3.
Здесь $$\alpha _{i} = a_{i(i+1)} < a_{i+1(i+2)}$$ ; индексация выполнена с
учетом попеременного формирования пар соседних элементов и с учетом их переименования после
пересылки; k — индекс последней анализируемой пары элементов; $$\beta$$ — предикат, принимающий значение "1",
если операция, при которой он указан, выполняется. Предполагается, что при
выходе за границу массива операция над элементами не производится. Далее
предполагается возможность взаимного обмена данными, инициированная в одном командном слове.
(рис 8.3) План программы пузырьковой сортировки
Программа не предполагает использование условных переходов и соответствует "теоретической" сложности, хотя время выполнения алгоритма при данной комплектации АЛУ сокращается почти в четыре раза по сравнению с применением одного ИУ.
Данный метод относится к "улучшенным". Он предполагает последовательные этапы разбиения исходного массива на несколько групп и их независимую сортировку.
Однако следует с осторожностью относиться к "улучшенным" методам сортировки, требующим значительных подготовительных работ и ориентированным на человека — вычислителя, для которого логический анализ действий не представляется сложным, а потому выносится за область учета трудоемкости. В компьютерной программе должно быть все учтено посредством формализованных действий.
На ранее выбранном массиве продемонстрируем сортировку Шелла.
Сначала выполняется A1 = {6, 4, 5}, A2 = {2, 7, 8}, A3 = {4, 10, 0}, A4 = {3, 9, 1}.
Каждая группа сортируется одним из известных
способов. Элементы возвращаются в массив с соблюдением тех же начала и
расстояния, с которыми они извлекались. Тогда результатом четверной сортировки будет
последовательность 4, 2, 0, 1, 5, 7, 4, 3, 6, 8, 10, 9.
На втором проходе элементы полученной последовательности
перегруппировываются — теперь каждый элемент группы отстоит от другого на две позиции. В данном
случае сформируются две группы: B1 = {4, 0, 5, 4, 6, 10} и B2 = {2, 1, 7, 3, 8, 9}.
Сортировка внутри групп ( 0, 1, 4, 2, 4, 3, 5, 7, 6, 8, 10, 9.
На третьем проходе окончательно производится обычная (
Исследования по выбору расстояний привели к теоретическому обоснованию
оценки сложности алгоритма, как O(n1,2). Эта сложность основана на
минимизации требуемых
пересылок.
Вполне очевидно, как существенно усложняется логика программы. Кроме того, если в заключение все равно необходимо выполнить единичную сортировку, то при планировании спекулятивного режима в рамках предикатных вычислений совершенно безразлично, выполняется ли операция пересылки, на которую выделены время и средства, или нет. Так что действительная сложность алгоритма, достигаемая на компьютере, значительно превосходит сложность алгоритмов сортировки, рассмотренных ранее.
Применение данного метода, очевидно, нецелесообразно на процессоре
Алгоритм сортировки предполагает следующие действия.
Реализуется и запоминается "пирамида" нахождения минимального элемента массива — формируется двоичное дерево, вершины которого отмечены сравниваемыми элементами массива (рис. 8.4).
(рис 8.4) Сортировка с помощью дерева: а — нахождение минимального элемента 0, б — нахождение элемента 1, в — нахождение элемента 2, г — нахождение элемента 3.
На рис. 8.4,а представлено двоичное дерево для нахождения минимального элемента 0 в ранее рассмотренном массиве. После исключения этого элемента находится минимальный элемент 1 из оставшихся, как показано на рис. 8.4,б.
После исключения этого элемента, элемент 5, как результат первого уровня сравнений, продвигается в вершину следующего уровня. Минимальный элемент находится, как показано на рис. 8.4,в.
Следующий шаг демонстрируется на рис 8.4,г и т.д. — до полного опустошения дерева.
Данный алгоритм имеет "теоретическую" сложность O(n log2n), рассчитанную на
основе оценок числа сравнений и пересылок и не учитывающую обслуживание
древовидной структуры. Известно, что графовые структуры, которые для параллельного
компьютера на уровне обработки целесообразно представлять
x.ai > x.
Если такого нет, за искомый элемент принимаем x.aj < x производим справа от x. Если такого нет, за искомый элемент принимаем x.ai и aj в случае их
неравенства.Сложность данного алгоритма, учитывающая лишь операции сравнения и
пересылки, но не организацию вычислений, составляет O(n log2 n).
Аппарат предикатных вычислений предусматривает симулятивный режим выполнения операций. Это означает, что минимизировать число операций (пересылок) нет необходимости, поскольку для выполнения этих операций выделены время и ресурсы, независимо от того, будут ли они выполнены. Избежать лишних пересылок можно с помощью условных переходов, но они-то и нежелательны. Кроме того, организация обмена местами элементов, когда эти места определяются в результате поиска, усложняет логику программы и адресацию данных, вносит элемент последовательного анализа.
Представим модификацию алгоритма быстрой сортировки, обеспечивающую простоту программной реализации.
x.x, образуют множество A, элементы, равные x, образуют
множество B, остальные элементы входят в множество C.A и C (элементы B уже
находятся на своем месте) шаги 1 и 2 до исчерпания образующихся подмножеств,
а следовательно, до завершения сортировки.В табл. 8.3 отображен процесс быстрой сортировки рассмотренного ранее массива. На каждом шаге производится преобразование всех сформированных на предыдущем шаге подмножеств (отмечены фигурными скобками), т.е. всего массива. Курсивом выделены элементы, относительно которых производится разбиение подмножеств.
Программу целесообразно планировать на основе циклически запускаемой
процедуры разбиения каждого ранее сформированного подмножества вида A и C на три новых, как указано в модифицированном алгоритме. При этом множества вида B пропускаются, так как для их элементов сортировка закончена.
| Исходный массив | 6 | 2 | 4 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Шаг 1 | {6 | 2 | 4 | 3 | 4 | 5 | 0 | 1} | {7} | {10 | 9 | 8} |
| Шаг 2 | {2 | 0 | 1} | {3} | {4 | 4} | {6 | 5} | 7 | {8} | {9} | {10} |
| Шаг 3 | {0} | {2 | 1} | 3 | 4 | 4 | {5} | {6} | 7 | 8 | 9 | 10 |
| Шаг 4 | 0 | {1} | {2} | 3 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Однако опытный программист здесь может обнаружить "скрытые" пересылки, обусловленные необходимостью "склеивания" динамически формируемых подмассивов, с их неопределенным, переменным началом. Необходимо учесть, что каждое разбиение на подмножества не меняет их суммарную длину. То есть подмножества формируются "на том же месте", и пересылки носят локальный характер внутри одних подмножеств, не нарушая структуру и расположение других.
При организации программы разбиения массива приходится все же пользоваться
значительным объемом дополнительной памяти. Только подмассив A
может располагаться (накапливаться) с начала разбиваемого массива. Подмассивы B и C, во избежание многократной коррекции расположения, целесообразно накапливать отдельно. При
этом начала подмассивов A и B, а также B и C, должны отстоять друг от друга не
менее чем на длину разбиваемого массива.
Экономия памяти достигается лишь тем, что после каждого разбиения
производится "склейка" массивов A, B и C
на месте разбитого массива.
Следует учесть, что каждое расширение используемой памяти приводит к увеличению числа "промахов" при обращении в кэш, а потому нежелательно.
План выполнения основной процедуры разбиения в применении к исходному массиву,в виде "развернутого" цикла, показан на рис. 8.5.
(рис 8.5) План программы быстрой сортировки
Таким образом, разбиение может производиться с использованием дополнительной памяти и продолжаться до вырождения подмножеств, что в конечном итоге приведет к получению упорядоченного массива.
Необходимо отметить, что время выполнения программы существенно зависит от организации кэша. Ведь сложность, помимо временной составляющей, имеет составляющую, отражающую затраты памяти. Так, если большой массив представляется в кэше по частям, то совместная обработка элементов, близко расположенных в памяти, имеет более низкую вероятность "промаха", чем элементов, далеко отстоящих друг от друга. Это замечание может служить еще одним доводом в пользу модифицированной пузырьковой сортировки.
Быстрая сортировка требует значительного увеличения затрат сверхоперативной памяти, что на деле может снизить быстродействие, т.к. приводит к увеличению числа "промахов" при обращении в кэш и, следовательно, к росту степени использования операционной системы в вычислительном процессе.
В этом отношении модифицированная "пузырьковая" сортировка универсальна, проста в реализации и не требует дополнительных ресурсов памяти.
Сортировка методом прямого включения также дает хорошую загрузку исполнительных устройств. Однако необходимость синхронизации пересылок на последнем этапе выполнения основной процедуры нахождения минимального элемента массива методом "пирамиды" может приводить к "разреженности" в выполнении команд во времени, к появлению пропущенных тактов. Следует учесть и необходимое увеличение вдвое объема используемой памяти.
Другие известные методы сортировки, как правило, ресурсоемки и не реализуют
"теоретическую" сложность алгоритмов при программной реализации,
включая программы процессора
Таким образом, отметим, что O(n log2 n). Программная
реализация этих методов достаточно проста, затраты на управление выполнением
программы (индексация, циклы) минимальны. Принцип предикатных вычислений и
спекулятивного режима выполнения операций дает значительный эффект и исключает
применение условных переходов. Он позволяет полностью загружать работой
исполнительные устройства процессора, обеспечивая высокую эффективность
распараллеливания.
Выше указывается на существование задач, для которых основным средством
решения является механизм ветвления. В процессорах "традиционной"
архитектуры ветвление производится с помощью последовательных логических проверок и условных передач
управления. Архитектура процессора
Если в задачах сортировки используются анализ и пересылки отдельных элементов массива, то в задачах поиска производится совместный анализ "массив с массивом", что значительно затрудняет решение проблемы минимизации числа условных переходов.
Поиск является одним из наиболее часто встречающихся действий при
программировании. Отметим важность таких задач, как текстовый анализ,
выделение подструктур генетического кода,
Задача поиска формулируется следующим образом.
Заданы массивы A = {a1, ..., an} (текст) и B = b1, ..., bm (слово, эталон).
Необходимо найти первое вхождение (индекс i ) в массив A таких следующих
подряд m элементов {ai, ai+1, ..., ai+m-1},
что ai+j-1 = bj, j = 1, ..., m.
Самый простой алгоритм поиска заключается в последовательном просмотре
текста — элементов множества A и их сравнением с первым элементом B. При положительном результате сравниваются следующие элементы массивов и т.д. В случае появления
отрицательного результата сравнения дальнейший анализ массива A
продолжается со следующего элемента. Сложность этого поиска составляет O(nm).
В табл. 8.4 представлен пример прямого поиска по шагам. Каждый шаг
обусловлен переходом, в случае несовпадения элементов, к анализу, начиная со следующего
элемента массива A.
| Массив | к | р | о | к | о | д | и | л |
|---|---|---|---|---|---|---|---|---|
| Эталон | к | о | д | |||||
| Шаг 1 | к | о | д | |||||
| Шаг 2 | к | о | д | |||||
| Шаг 3 | к | о | д |
На рис. 8.6 представлен план программы прямого поиска. Каждая явно наблюдаемая строка соответствует параллельно выполняемым командам, отображенным в одном "длинном" командном слове. Столбец соответствует одному исполнительному устройству (ИУ). Внутренний цикл попарного сравнения элементов массивов показан в развернутом виде.
(рис 8.6) План программы прямого поиска
Предусмотрено многократное выполнение команды условного перехода на
продолжение циклического перебора элементов массива A. Эти команды
выполняются в спекулятивном режиме и требуют единственной подготовительной команды запуска
дополнительного конвейера. В случае первого несовпадения элементов массива и
эталона единственный раз выполняется условный переход.
Начальное смещение команд сравнения выполнено в предположении о необходимости двух тактов для возможного использования результата.
Следует признать высокую эффективность распараллеливания — высокий коэффициент использования ИУ и достижимость "теоретической" сложности алгоритма.
Данный алгоритм предложен Д. Кнутом, Д. Морисом и В. Праттом [10] и основан на соображении, что в процессе сравнения накапливается полезная информация, которую можно использовать в последующем поиске, "перескакивая" по тексту вперед. А именно, если произошло совпадение при сравнении текста с несколькими начальными символами слова, а затем последовал отрицательный результат сравнения, то для продолжения поиска необходимо сместиться по тексту на число совпавших символов.
В табл. 8.5 показан пример поиска по данному алгоритму. Совпавшие символы на каждом шаге выделены курсивом. Показано, что в случае совпадения двух символов сдвиг слова для последующего сравнения производится на две позиции.
Однако иллюстрируется упрощенный подход. Действительный алгоритм значительно
сложнее и основан на предварительном исследовании слова B — на
составлении таблицы значений, определяющих величину сдвига при частичном совпадении
символов. Такая обработка слова оправдана при значительных размерах текста и при
многократном поиске вхождения слова.
Авторы утверждают, что сложность метода составляет O(n+m).
| Текст | е | л | е | - | е | л | е | — | с | р | у | б | и | л | и | Е | л | ь |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Слово | е | л | ь | |||||||||||||||
| Шаг 2 | е | л | ь | |||||||||||||||
| Шаг 3 | е | л | ь | |||||||||||||||
| Шаг 4 | е | л | ь | |||||||||||||||
| Шаг 5 | е | л | ь | |||||||||||||||
| ... | ||||||||||||||||||
| Шаг 15 | е | л | ь | |||||||||||||||
На рис. 8.7 представлен план программы для упрощенного варианта КМП-поиска. Анализ этого плана показывает, что, несмотря на усложнившуюся логику, возможно получение компактной программы при некоторых допущениях относительно особенностей выполнения операций. Например, считаем, что условный переход, обозначенный в "длинной" команде, выполняется после окончания выполнения всех операций, предусмотренных в этой же команде.
(рис 8.7) План программы КМП-поиска
Структура программы подтверждает принципиальную достижимость "теоретической" сложности упрощенного алгоритма КМП-поиска (она, конечно, выше той, что объявлена авторами). Однако общий случай, требующий расчета специальных таблиц сдвига слова-эталона вдоль текста, приводит к высокой трудоемкости и к сложной логике программы. При существовании других методов полиномиальной сложности использование такого метода нецелесообразно.
КМП-поиск дает выигрыш только тогда, когда неудаче предшествовало некоторое число совпадений. В этом случае искомое слово (эталон, образ) сдвигается по тексту более чем на одну позицию.
Однако совпадение символов встречается гораздо реже, чем несовпадение. В связи с этим, Р. Буер и Д. Мур предложили [10] метод, где сравнение символов начинается не с начала, а с конца слова. При обнаружении расхождения между словом и текстом слово сдвигается вправо. Для определения длины сдвига, как и в общем случае КМП-поиска, используется ранее построенная таблица. Иногда слово сдвигается вправо на всю свою длину.
Сложность метода имеет порядок O(n).
Для КМП-поиска удается построить упрощенный вариант, допускающий эффективное программирование. Однако указанная сложность БМ-поиска, по-видимому, носит рекламный характер и не учитывает затрат трудоемкости как на предварительную подготовку таблиц, так и на развившуюся логику программы. Реализация противоположных направлений анализа слова и текста, переменной длины их относительного смещения при наличии многих альтернатив порождает программу весьма большого объема и значительного времени выполнения.
Очевидно, что объявленная "теоретическая" сложность алгоритма
недостижима даже на параллельном процессоре
Таким образом, зачастую объявленная "теоретическая" сложность
алгоритмов не затрагивает все подготовительные работы или неизбежные затраты на организацию
вычислительного процесса, которые значительно увеличивают реальную сложность,
достигаемую при оптимальном программировании. Это касается и задач поиска при
их реализации на процессоре столь развитой архитектуры, какой является
Учитывая высокое быстродействие при развитом параллелизме, а также полиномиальную сложность методов, целесообразно применение таких методов поиска, как прямой поиск и упрощенный КМП-поиск.
Выше предложен алгоритм компоновки "длинных" командных слов
внутри линейного участка программы для
Очевидно, что для разных задач различна и актуальность механизмов ветвления. Существуют задачи, для которых этот механизм является основным средством решения. По-видимому, такие задачи целесообразно выбрать в качестве тестовых для оценки эффективности ветвления.
В теории алгоритмов на задачах сортировки принято оценивать возможность
снижения
Понятие O(n log2n),
где n — длина массива.
Однако выше речь идет о сложности алгоритма, а не о его реализации на компьютере. Компьютер, в результате слабой "профпригодности", может внести значительные коррективы сложности в худшую сторону.
Конечно, не всегда в этом случае виноват компьютер. При расчете сложности зачастую не учитываются объективно существующие затраты на организацию вычислительного процесса. Например, древовидная (графовая) структура требует значительных вычислительных затрат на обслуживание. Человек, производя сортировку "вручную", на неформальном уровне с легкостью производит логические действия, которые весьма трудоемки для компьютера.
Таким образом, необходимо:
В то же время, составляя планы программ сортировки, будем высказывать предположения или рекомендации относительно возможностей системы команд процессора.
Обобщенная программистская модель процессора EPIC-архитектуры
Под программистской моделью понимают то, что "видит"
программист (транслятор) в вычислительной системе и что достаточно для написания "хорошей"
программы. Ранее это называлось "
Так как нас интересует программа в виде расписания работы исполнительных
устройств (ИУ) арифметическо-логического устройства (АЛУ), будем составлять
планы компоновки таких расписаний, ориентируясь на
Для данной задачи достаточно рассматривать два логических ИУ. Пусть также используются два ИУ обмена информацией. Для оценки принципиальных возможностей оптимального программирования указанные параметры АЛУ несущественны.
Предположим, что все ИУ конвейерные, т.е. известно количество тактов счета
результатов. Существуют
Предикатные (логические) вычисления выполняются с помощью адресуемой памяти
(файла) предикатов
Предполагается аппаратная поддержка циклов, основанная на автоматическом переиспользовании (переименовании) регистров и исключающая остановки конвейера выполнения команд.
Целью сортировки является переформирование массива данных в порядке их невозрастания.
Данный метод заключается в том, что исходный массив условно делится на две части: уже отсортированную и еще не отсортированную. Первоначально отсортированная часть содержит лишь один, первый, элемент массива. Затем на каждом шаге первый элемент неотсортированной части вставляется в отсортированную часть на свое место с учетом упорядоченности.
Пусть задан массив a[1...12] = {6, 2, 4, 3, 4, 7, 10, 9, 5, 8, 0, 1}.
В табл. 8.1 отражен процесс сортировки по шагам, где курсивом выделена
упорядоченная часть массива.
Известны [10] оценки общего числа Cср
сравнений и Mпер пересылок:
$$C_{ср} = (n{}^2 + n - 2)/4$$,
$$M_{пер} = (n{}^2 + n - 2)/4$$,
что подтверждает оценку $$O(n{}^2 )$$.
| Исходный массив | 6 | 2 | 4 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Шаг 1 | 2 | 6 | 4 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
| Шаг 2 | 2 | 4 | 6 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
| Шаг 3 | 2 | 3 | 4 | 6 | 4 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
| Шаг 4 | 2 | 3 | 4 | 4 | 6 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
| Шаг 5 | 2 | 3 | 4 | 4 | 6 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
| Шаг 6 | 2 | 3 | 4 | 4 | 6 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
| Шаг 7 | 2 | 3 | 4 | 4 | 6 | 7 | 9 | 10 | 5 | 8 | 0 | 1 |
| Шаг 8 | 2 | 3 | 4 | 4 | 5 | 6 | 7 | 9 | 10 | 8 | 0 | 1 |
| Шаг 9 | 2 | 3 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 0 | 1 |
| Шаг 10 | 0 | 2 | 3 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 1 |
| Шаг 11 | 0 | 1 | 2 | 3 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Однако, пытаясь запрограммировать этот метод для параллельного АЛУ, мы сталкиваемся с преобладанием операций, выполняемых над элементами массива строго последовательно:
Метод явно нуждается в модификации, что при наличии других, ниже рассматриваемых, методов сортировки вряд ли целесообразно.
Общий принцип алгоритма:
n — 1 элементов, n — 2 элементов и т.д.
и меняется местами с первым элементом оставшейся части массива. Процесс
продолжается до тех пор, пока справа не останется один, самый большой элемент
исходного массива.Сложность алгоритма составляет $$O(n{}^2 )$$.
В табл. 8.2 показана по шагам сортировка того же массива. Курсивом выделены меняющиеся на каждом шаге местами первый и минимальный элементы неупорядоченной части массива.
Основная процедура, многократно применяемая в алгоритме — процедура нахождения минимального элемента среди уменьшающегося множества элементов.
Рассмотрим эту процедуру отдельно. В ней реализуется операция преобразования
вектора (массива) в скаляр, что также соответствует сложению или умножению всех
элементов массива. Эта операция является составной частью ]log2n[t, где t — время элементарной,
образующей операции (сравнения и возможной пересылки).
При использовании небольшого числа ИУ возможна их практически полная
загрузка на всем протяжении счета при наличии
| Исходный массив | 6 | 2 | 4 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Шаг 1 | 0 | 2 | 4 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 6 | 1 |
| Шаг 2 | 0 | 1 | 4 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 6 | 2 |
| Шаг 3 | 0 | 1 | 2 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 6 | 4 |
| Шаг 4 | 0 | 1 | 2 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 6 | 4 |
| Шаг 5 | 0 | 1 | 2 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 6 | 7 |
| Шаг 6 | 0 | 1 | 2 | 3 | 4 | 4 | 10 | 9 | 5 | 8 | 6 | 7 |
| Шаг 7 | 0 | 1 | 2 | 3 | 4 | 4 | 5 | 9 | 10 | 8 | 6 | 7 |
| Шаг 8 | 0 | 1 | 2 | 3 | 4 | 4 | 5 | 6 | 10 | 8 | 9 | 7 |
| Шаг 9 | 0 | 1 | 2 | 3 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| Шаг 10 | 0 | 1 | 2 | 3 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Представим схему счета "пирамидой" при нахождении минимального
элемента массива, на основе которой составим план программы для процессора n-1
элементами — промежуточными результатами анализа, а также (последний элемент) результатом поиска.
Для схемы счета "пирамидой" не принципиальна четность или
степень "двойки" значения n. На рис. 8.1 представлена схема
для n = 7.
(рис 8.1) Схема счёта "пирамидой"
Стрелки указывают на направление движения информации, $$\alpha _{1}$$ — $$\alpha _{6}$$ — значения предикатов — результатов попарного сравнения элементов.
Рисунок иллюстрирует простой цикл сравнения и пересылок меньших элементов. Единственным условием правильного выполнения операции является, как говорилось ранее, синхронизация, исключающая использование результата сравнения до окончания его формирования. При длине массива, значительно превышающей количество ИУ, эффективен механизм ожидания рассчитываемого результата, т.е. задержки выполнения команд при попытке считывания до записи. Задержки начнутся только на последнем этапе выполнения "пирамиды".
Однако отметим преимущества принудительного программного решения проблемы
синхронизации с помощью команды закрытия адресов по считыванию до окончания
записи по этим адресам. Такая команда позволяет предварительно закрыть адреса
данных an+1 - a2n-1. Их открытие при записи в ходе
выполнения программы обеспечивает правильное выполнение "пирамиды" во времени.
План программы выполнения данной процедуры представлен на рис. 8.2. Иллюстрируется "развернутый" цикл, где ромбами обозначены операции сравнения $$\alpha _{i} = a_{i} < a_{i+1}$$. Пересылки помечены предикатами или их отрицаниями, в соответствии со значениями которых они производятся. Считаем, что значение предиката может быть использовано через два такта, что определяет взаимное смещение пересылок и сравнений при формировании "длинных" командных слов. При формировании программы необходимо учесть организацию цикла, индексацию и т.д. Однако важно отметить, что все ветвление в данном проекте программы выполнено без остановок конвейера.
(рис 8.2) План программы счёта "пирамидой"
Тогда очевиден план программы сортировки с помощью прямого выбора. Процедура нахождения минимального элемента выполняется в цикле над уменьшающейся на единицу длиной массива. Найденный элемент меняется местами с первым элементом этого массива. Очевидно, в этом случае условный переход не используется.
Алгоритм этой сортировки заключается в последовательном сравнении и смене мест (если необходимо) пар соседних элементов массива. Процесс продолжается до тех пор, пока обмены не прекратятся. Сложность алгоритма также составляет $$O(n{}^2 )$$.
Легко видеть, что последовательный учет результатов предыдущего сравнения (последовательное всплытие "пузырьков") не допускает распараллеливания. Алгоритм нуждается в модификации.
Для эффективного распараллеливания на процессоре
Для этого при каждом обзоре текущее (частично упорядоченное) множество элементов разбивается на пары. При первом (нечетном) обзоре первая пара включает первый элемент массива. При втором (четном) обзоре группирование начинается со второго элемента и т.д. Внутри пар элементы упорядочиваются, при необходимости меняясь местами так, чтобы слева стоял меньший элемент. Наличие обменов при каждом просмотре фиксируется. Их прекращение свидетельствует об окончании сортировки массива.
Ниже по шагам (обзорам) отражена сортировка ранее рассмотренного
массива. Формируемые на каждом шаге пары элементов выделены. При четном n
нечетные шаги сортировки требуют анализа k = n/2 пар элементов, четные шаги
требуют анализа k = (n/2) - 1. При нечетном n k = [n/2] пар
элементов.
План программы (внутренний цикл развернут) представлен на рис. 8.3.
Здесь $$\alpha _{i} = a_{i(i+1)} < a_{i+1(i+2)}$$ ; индексация выполнена с
учетом попеременного формирования пар соседних элементов и с учетом их переименования после
пересылки; k — индекс последней анализируемой пары элементов; $$\beta$$ — предикат, принимающий значение "1",
если операция, при которой он указан, выполняется. Предполагается, что при
выходе за границу массива операция над элементами не производится. Далее
предполагается возможность взаимного обмена данными, инициированная в одном командном слове.
(рис 8.3) План программы пузырьковой сортировки
Программа не предполагает использование условных переходов и соответствует "теоретической" сложности, хотя время выполнения алгоритма при данной комплектации АЛУ сокращается почти в четыре раза по сравнению с применением одного ИУ.
Данный метод относится к "улучшенным". Он предполагает последовательные этапы разбиения исходного массива на несколько групп и их независимую сортировку.
Однако следует с осторожностью относиться к "улучшенным" методам сортировки, требующим значительных подготовительных работ и ориентированным на человека — вычислителя, для которого логический анализ действий не представляется сложным, а потому выносится за область учета трудоемкости. В компьютерной программе должно быть все учтено посредством формализованных действий.
На ранее выбранном массиве продемонстрируем сортировку Шелла.
Сначала выполняется A1 = {6, 4, 5}, A2 = {2, 7, 8}, A3 = {4, 10, 0}, A4 = {3, 9, 1}.
Каждая группа сортируется одним из известных
способов. Элементы возвращаются в массив с соблюдением тех же начала и
расстояния, с которыми они извлекались. Тогда результатом четверной сортировки будет
последовательность 4, 2, 0, 1, 5, 7, 4, 3, 6, 8, 10, 9.
На втором проходе элементы полученной последовательности
перегруппировываются — теперь каждый элемент группы отстоит от другого на две позиции. В данном
случае сформируются две группы: B1 = {4, 0, 5, 4, 6, 10} и B2 = {2, 1, 7, 3, 8, 9}.
Сортировка внутри групп ( 0, 1, 4, 2, 4, 3, 5, 7, 6, 8, 10, 9.
На третьем проходе окончательно производится обычная (
Исследования по выбору расстояний привели к теоретическому обоснованию
оценки сложности алгоритма, как O(n1,2). Эта сложность основана на
минимизации требуемых
пересылок.
Вполне очевидно, как существенно усложняется логика программы. Кроме того, если в заключение все равно необходимо выполнить единичную сортировку, то при планировании спекулятивного режима в рамках предикатных вычислений совершенно безразлично, выполняется ли операция пересылки, на которую выделены время и средства, или нет. Так что действительная сложность алгоритма, достигаемая на компьютере, значительно превосходит сложность алгоритмов сортировки, рассмотренных ранее.
Применение данного метода, очевидно, нецелесообразно на процессоре
Алгоритм сортировки предполагает следующие действия.
Реализуется и запоминается "пирамида" нахождения минимального элемента массива — формируется двоичное дерево, вершины которого отмечены сравниваемыми элементами массива (рис. 8.4).
(рис 8.4) Сортировка с помощью дерева: а — нахождение минимального элемента 0, б — нахождение элемента 1, в — нахождение элемента 2, г — нахождение элемента 3.
На рис. 8.4,а представлено двоичное дерево для нахождения минимального элемента 0 в ранее рассмотренном массиве. После исключения этого элемента находится минимальный элемент 1 из оставшихся, как показано на рис. 8.4,б.
После исключения этого элемента, элемент 5, как результат первого уровня сравнений, продвигается в вершину следующего уровня. Минимальный элемент находится, как показано на рис. 8.4,в.
Следующий шаг демонстрируется на рис 8.4,г и т.д. — до полного опустошения дерева.
Данный алгоритм имеет "теоретическую" сложность O(n log2n), рассчитанную на
основе оценок числа сравнений и пересылок и не учитывающую обслуживание
древовидной структуры. Известно, что графовые структуры, которые для параллельного
компьютера на уровне обработки целесообразно представлять
x.ai > x.
Если такого нет, за искомый элемент принимаем x.aj < x производим справа от x. Если такого нет, за искомый элемент принимаем x.ai и aj в случае их
неравенства.Сложность данного алгоритма, учитывающая лишь операции сравнения и
пересылки, но не организацию вычислений, составляет O(n log2 n).
Аппарат предикатных вычислений предусматривает симулятивный режим выполнения операций. Это означает, что минимизировать число операций (пересылок) нет необходимости, поскольку для выполнения этих операций выделены время и ресурсы, независимо от того, будут ли они выполнены. Избежать лишних пересылок можно с помощью условных переходов, но они-то и нежелательны. Кроме того, организация обмена местами элементов, когда эти места определяются в результате поиска, усложняет логику программы и адресацию данных, вносит элемент последовательного анализа.
Представим модификацию алгоритма быстрой сортировки, обеспечивающую простоту программной реализации.
x.x, образуют множество A, элементы, равные x, образуют
множество B, остальные элементы входят в множество C.A и C (элементы B уже
находятся на своем месте) шаги 1 и 2 до исчерпания образующихся подмножеств,
а следовательно, до завершения сортировки.В табл. 8.3 отображен процесс быстрой сортировки рассмотренного ранее массива. На каждом шаге производится преобразование всех сформированных на предыдущем шаге подмножеств (отмечены фигурными скобками), т.е. всего массива. Курсивом выделены элементы, относительно которых производится разбиение подмножеств.
Программу целесообразно планировать на основе циклически запускаемой
процедуры разбиения каждого ранее сформированного подмножества вида A и C на три новых, как указано в модифицированном алгоритме. При этом множества вида B пропускаются, так как для их элементов сортировка закончена.
| Исходный массив | 6 | 2 | 4 | 3 | 4 | 7 | 10 | 9 | 5 | 8 | 0 | 1 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Шаг 1 | {6 | 2 | 4 | 3 | 4 | 5 | 0 | 1} | {7} | {10 | 9 | 8} |
| Шаг 2 | {2 | 0 | 1} | {3} | {4 | 4} | {6 | 5} | 7 | {8} | {9} | {10} |
| Шаг 3 | {0} | {2 | 1} | 3 | 4 | 4 | {5} | {6} | 7 | 8 | 9 | 10 |
| Шаг 4 | 0 | {1} | {2} | 3 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Однако опытный программист здесь может обнаружить "скрытые" пересылки, обусловленные необходимостью "склеивания" динамически формируемых подмассивов, с их неопределенным, переменным началом. Необходимо учесть, что каждое разбиение на подмножества не меняет их суммарную длину. То есть подмножества формируются "на том же месте", и пересылки носят локальный характер внутри одних подмножеств, не нарушая структуру и расположение других.
При организации программы разбиения массива приходится все же пользоваться
значительным объемом дополнительной памяти. Только подмассив A
может располагаться (накапливаться) с начала разбиваемого массива. Подмассивы B и C, во избежание многократной коррекции расположения, целесообразно накапливать отдельно. При
этом начала подмассивов A и B, а также B и C, должны отстоять друг от друга не
менее чем на длину разбиваемого массива.
Экономия памяти достигается лишь тем, что после каждого разбиения
производится "склейка" массивов A, B и C
на месте разбитого массива.
Следует учесть, что каждое расширение используемой памяти приводит к увеличению числа "промахов" при обращении в кэш, а потому нежелательно.
План выполнения основной процедуры разбиения в применении к исходному массиву,в виде "развернутого" цикла, показан на рис. 8.5.
(рис 8.5) План программы быстрой сортировки
Таким образом, разбиение может производиться с использованием дополнительной памяти и продолжаться до вырождения подмножеств, что в конечном итоге приведет к получению упорядоченного массива.
Необходимо отметить, что время выполнения программы существенно зависит от организации кэша. Ведь сложность, помимо временной составляющей, имеет составляющую, отражающую затраты памяти. Так, если большой массив представляется в кэше по частям, то совместная обработка элементов, близко расположенных в памяти, имеет более низкую вероятность "промаха", чем элементов, далеко отстоящих друг от друга. Это замечание может служить еще одним доводом в пользу модифицированной пузырьковой сортировки.
Быстрая сортировка требует значительного увеличения затрат сверхоперативной памяти, что на деле может снизить быстродействие, т.к. приводит к увеличению числа "промахов" при обращении в кэш и, следовательно, к росту степени использования операционной системы в вычислительном процессе.
В этом отношении модифицированная "пузырьковая" сортировка универсальна, проста в реализации и не требует дополнительных ресурсов памяти.
Сортировка методом прямого включения также дает хорошую загрузку исполнительных устройств. Однако необходимость синхронизации пересылок на последнем этапе выполнения основной процедуры нахождения минимального элемента массива методом "пирамиды" может приводить к "разреженности" в выполнении команд во времени, к появлению пропущенных тактов. Следует учесть и необходимое увеличение вдвое объема используемой памяти.
Другие известные методы сортировки, как правило, ресурсоемки и не реализуют
"теоретическую" сложность алгоритмов при программной реализации,
включая программы процессора
Таким образом, отметим, что O(n log2 n). Программная
реализация этих методов достаточно проста, затраты на управление выполнением
программы (индексация, циклы) минимальны. Принцип предикатных вычислений и
спекулятивного режима выполнения операций дает значительный эффект и исключает
применение условных переходов. Он позволяет полностью загружать работой
исполнительные устройства процессора, обеспечивая высокую эффективность
распараллеливания.
Выше указывается на существование задач, для которых основным средством
решения является механизм ветвления. В процессорах "традиционной"
архитектуры ветвление производится с помощью последовательных логических проверок и условных передач
управления. Архитектура процессора
Если в задачах сортировки используются анализ и пересылки отдельных элементов массива, то в задачах поиска производится совместный анализ "массив с массивом", что значительно затрудняет решение проблемы минимизации числа условных переходов.
Поиск является одним из наиболее часто встречающихся действий при
программировании. Отметим важность таких задач, как текстовый анализ,
выделение подструктур генетического кода,
Задача поиска формулируется следующим образом.
Заданы массивы A = {a1, ..., an} (текст) и B = b1, ..., bm (слово, эталон).
Необходимо найти первое вхождение (индекс i ) в массив A таких следующих
подряд m элементов {ai, ai+1, ..., ai+m-1},
что ai+j-1 = bj, j = 1, ..., m.
Самый простой алгоритм поиска заключается в последовательном просмотре
текста — элементов множества A и их сравнением с первым элементом B. При положительном результате сравниваются следующие элементы массивов и т.д. В случае появления
отрицательного результата сравнения дальнейший анализ массива A
продолжается со следующего элемента. Сложность этого поиска составляет O(nm).
В табл. 8.4 представлен пример прямого поиска по шагам. Каждый шаг
обусловлен переходом, в случае несовпадения элементов, к анализу, начиная со следующего
элемента массива A.
| Массив | к | р | о | к | о | д | и | л |
|---|---|---|---|---|---|---|---|---|
| Эталон | к | о | д | |||||
| Шаг 1 | к | о | д | |||||
| Шаг 2 | к | о | д | |||||
| Шаг 3 | к | о | д |
На рис. 8.6 представлен план программы прямого поиска. Каждая явно наблюдаемая строка соответствует параллельно выполняемым командам, отображенным в одном "длинном" командном слове. Столбец соответствует одному исполнительному устройству (ИУ). Внутренний цикл попарного сравнения элементов массивов показан в развернутом виде.
(рис 8.6) План программы прямого поиска
Предусмотрено многократное выполнение команды условного перехода на
продолжение циклического перебора элементов массива A. Эти команды
выполняются в спекулятивном режиме и требуют единственной подготовительной команды запуска
дополнительного конвейера. В случае первого несовпадения элементов массива и
эталона единственный раз выполняется условный переход.
Начальное смещение команд сравнения выполнено в предположении о необходимости двух тактов для возможного использования результата.
Следует признать высокую эффективность распараллеливания — высокий коэффициент использования ИУ и достижимость "теоретической" сложности алгоритма.
Данный алгоритм предложен Д. Кнутом, Д. Морисом и В. Праттом [10] и основан на соображении, что в процессе сравнения накапливается полезная информация, которую можно использовать в последующем поиске, "перескакивая" по тексту вперед. А именно, если произошло совпадение при сравнении текста с несколькими начальными символами слова, а затем последовал отрицательный результат сравнения, то для продолжения поиска необходимо сместиться по тексту на число совпавших символов.
В табл. 8.5 показан пример поиска по данному алгоритму. Совпавшие символы на каждом шаге выделены курсивом. Показано, что в случае совпадения двух символов сдвиг слова для последующего сравнения производится на две позиции.
Однако иллюстрируется упрощенный подход. Действительный алгоритм значительно
сложнее и основан на предварительном исследовании слова B — на
составлении таблицы значений, определяющих величину сдвига при частичном совпадении
символов. Такая обработка слова оправдана при значительных размерах текста и при
многократном поиске вхождения слова.
Авторы утверждают, что сложность метода составляет O(n+m).
| Текст | е | л | е | - | е | л | е | — | с | р | у | б | и | л | и | Е | л | ь |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Слово | е | л | ь | |||||||||||||||
| Шаг 2 | е | л | ь | |||||||||||||||
| Шаг 3 | е | л | ь | |||||||||||||||
| Шаг 4 | е | л | ь | |||||||||||||||
| Шаг 5 | е | л | ь | |||||||||||||||
| ... | ||||||||||||||||||
| Шаг 15 | е | л | ь | |||||||||||||||
На рис. 8.7 представлен план программы для упрощенного варианта КМП-поиска. Анализ этого плана показывает, что, несмотря на усложнившуюся логику, возможно получение компактной программы при некоторых допущениях относительно особенностей выполнения операций. Например, считаем, что условный переход, обозначенный в "длинной" команде, выполняется после окончания выполнения всех операций, предусмотренных в этой же команде.
(рис 8.7) План программы КМП-поиска
Структура программы подтверждает принципиальную достижимость "теоретической" сложности упрощенного алгоритма КМП-поиска (она, конечно, выше той, что объявлена авторами). Однако общий случай, требующий расчета специальных таблиц сдвига слова-эталона вдоль текста, приводит к высокой трудоемкости и к сложной логике программы. При существовании других методов полиномиальной сложности использование такого метода нецелесообразно.
КМП-поиск дает выигрыш только тогда, когда неудаче предшествовало некоторое число совпадений. В этом случае искомое слово (эталон, образ) сдвигается по тексту более чем на одну позицию.
Однако совпадение символов встречается гораздо реже, чем несовпадение. В связи с этим, Р. Буер и Д. Мур предложили [10] метод, где сравнение символов начинается не с начала, а с конца слова. При обнаружении расхождения между словом и текстом слово сдвигается вправо. Для определения длины сдвига, как и в общем случае КМП-поиска, используется ранее построенная таблица. Иногда слово сдвигается вправо на всю свою длину.
Сложность метода имеет порядок O(n).
Для КМП-поиска удается построить упрощенный вариант, допускающий эффективное программирование. Однако указанная сложность БМ-поиска, по-видимому, носит рекламный характер и не учитывает затрат трудоемкости как на предварительную подготовку таблиц, так и на развившуюся логику программы. Реализация противоположных направлений анализа слова и текста, переменной длины их относительного смещения при наличии многих альтернатив порождает программу весьма большого объема и значительного времени выполнения.
Очевидно, что объявленная "теоретическая" сложность алгоритма
недостижима даже на параллельном процессоре
Таким образом, зачастую объявленная "теоретическая" сложность
алгоритмов не затрагивает все подготовительные работы или неизбежные затраты на организацию
вычислительного процесса, которые значительно увеличивают реальную сложность,
достигаемую при оптимальном программировании. Это касается и задач поиска при
их реализации на процессоре столь развитой архитектуры, какой является
Учитывая высокое быстродействие при развитом параллелизме, а также полиномиальную сложность методов, целесообразно применение таких методов поиска, как прямой поиск и упрощенный КМП-поиск.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.