Общий метод увеличения производительности – организация параллельной обработки информации, т. е. одновременное решение задач или совмещение во времени этапов решения одной задачи.
Способы организации. Во всем многообразии способов организации параллельной обработки можно выделить три основных направления:
1) совмещение во времени различных этапов разных задач;
2) одновременное решение различных задач или частей одной задачи;
3) конвейерная обработка информации.
Первый путь – совмещение во времени этапов решения разных задач – это мультипрограммная обработка информации. Мультипрограммная обработка возможна даже в однопроцессорной ЭВМ.
Второй путь – одновременное решение различных задач или частей одной задачи – возможен только при наличии нескольких обрабатывающих устройств. При этом используются те или иные особенности задач или потоков задач, что позволяет осуществить тот или иной параллелизм. Можно выделить несколько типов параллелизма, отражающих эти особенности.
Естественный параллелизм независимых задач заключается в том, что в систему поступает непрерывный поток не связанных между собой задач, т. е. решение любой задачи не зависит от результатов решения других задач. В этом случае использование нескольких обрабатывающих устройств при любом способе комплексирования (косвенном или прямом) повышает производительность системы.
Параллелизм независимых ветвей – один из наиболее распространенных типов параллелизма в обработке информации. Суть его заключается в том, что при решении большой задачи могут быть выделены отдельные независимые части – ветви программы, которые при наличии нескольких обрабатывающих устройств могут выполняться параллельно и независимо друг от друга. Двумя независимыми ветвями программы будем считать такие части задачи, при выполнении которых выполняются следующие условия:
ни одна из входных для ветви программы величин не является выходной величиной другой программы (отсутствие функциональных связей);
для обеих ветвей программы не должна производиться запись в одни и те же ячейки памяти (отсутствие связи по использованию одних и тех же полей оперативной памяти);
условия выполнения одной ветви не зависят от результатов или признаков, полученных при выполнении другой ветви (независимость по управлению);
обе ветви должны выполняться по разным блокам программы (программная независимость).
Хорошее представление о параллелизме независимых ветвей дает ярусно-параллельная форма программы, пример которой приведен на рис. 2.1. Программа представлена в виде совокупности ветвей, расположенных в нескольких уровнях – ярусах. Кружками с цифрами внутри обозначены ветви. Длина ветви представляется цифрой, стоящей около кружка. Стрелками показаны входные данные и результаты обработки. Входные данные обозначаются символом х, выходные данные – символом у. Символы х имеют нижние цифровые индексы, означающие номера входных величин; символы у имеют цифровые индексы и внизу и вверху; цифра вверху соответствует номеру ветви, при выполнении которой получен данный результат, а цифра внизу означает порядковый номер результата, полученного при реализации данной ветви программы.
Рис. 2.1. Ярусно-параллельная форма программы
Изображенная на рисунке программа содержит 14 ветвей, расположенных на 5 ярусах. Ветви каждого яруса не связаны друг с другом, т. е. результаты решения какой-либо ветви данного яруса не являются входными данными для другой ветви этого же яруса. На этом же графе могут быть изображены и связи по управлению или памяти. В этом случае граф позволяет наглядно показать полностью независимые ветви. Для простоты изображения мы этого не делаем.
На примере этой, в общем достаточно простой программы, можно выявить преимущества вычислительной системы, включающей несколько обрабатывающих устройств, и проблемы, которые при этом возникают.
Примем, что длина i-й ветви представляется числом временных единиц ti, которые требуются для ее исполнения. Тогда нетрудно подсчитать, что для исполнения всей программы потребуется единиц времени. Если представить, что программа выполняется двумя обрабатывающими устройствами, работающими независимо друг от друга, то время решения задачи сократится. Однако это время, как нетрудно видеть, будет различным в зависимости от последовательности выполнения независимых ветвей.
Для того чтобы с помощью нескольких обрабатывающих устройств решить задачу, имеющую независимые параллельные ветви, необходима соответствующая организация процесса, которая определяет пути решения задачи и вырабатывает необходимую информацию о готовности каждой ветви. Заметим, что все это относительно легко реализовать тогда, когда известна достаточно точно длительность выполнения каждой ветви, На практике это бывает крайне редко: в лучшем случае известна приближенная длина ветвей. Поэтому организация оптимального или близкого к оптимальному графика работы является достаточно сложной задачей.
Заметим, что, как правило, трудно избежать некоторых простоев, которые возникают из-за отсутствия исходных данных для выполнения той или иной ветви. Все это приводит в конечном счете к тому, что выигрыш в производительности системы несколько снижается. Следует отметить также и определенные сложности, связанные с выделением независимых ветвей при разработке программ. Вместе с тем при решении многих сложных задач только программирование с выделением независимых ветвей позволяет существенно сократить время решения.
Параллелизм объектов или данных имеет место тогда, когда по одной и той же (или почти по одной и той же) программе должна обрабатываться некоторая совокупность данных, поступающих в систему одновременно.
Это могут быть, например, задачи обработки сигналов от радиолокационной станции: все сигналы обрабатываются по одной и той же программе. Другой пример – обработка информации от датчиков, измеряющих одновременно один и тот же параметр и установленных на нескольких однотипных объектах. Программы обработки данных могут быть различного объема и сложности, начиная от очень простых, содержащих несколько операций, до больших программ в сотни и тысячи операций.
Это могут быть и чисто математические задачи, например задачи векторной алгебры – операции над векторами и матрицами, характеризующиеся некоторой совокупностью чисел. Решение задачи при этом в значительной степени сводится к выполнению одинаковых операций над парами чисел двух аналогичных объектов. Так, например, сложение двух матриц размерностью заключается в сложении соответствующих элементов этих матриц. При этом операция сложения должна быть проведена над парами чисел. Произведение матрицы размерностью на скаляр сводится к выполнению умножений элементов матрицы на скаляр: и т. д. Очевидно, все эти операции могут выполняться параллельно и независимо друг от друга несколькими обрабатывающими устройствами.
Третий путь параллельной обработки информации – конвейерная обработка – может быть реализован в системе и с одним процессором, разделенным на некоторое число последовательно включенных операционных блоков, каждый из которых специализирован на выполнении строго определенной части операции.(Принцип работы конвейера был рассмотрен при изучении МП.)
Напомним, работу конвейера для обработки данных можно представить следующей схемой.
Процессор работает таким образом: когда i-й операционный блок выполняет i-о часть j-й операции, (i–1)-й операционный блок выполняет (i–1)-ю часть (j+1)-й операции, а (i+1)-и операционный блок выполняет (i+1)-ю часть (j–1)-й операции. В результате образуется своего рода конвейер обработки, который хорошо может быть проиллюстрирован следующим простым примером.
Рис. 2.2. Структурная схема конвейера операций
Операцию сложения двух чисел с плавающей запятой можно разделить на четыре последовательно исполняемых этапа, или шага: сравнение порядков (СП); выравнивание порядков – сдвиг мантиссы с меньшим порядком для выравнивания с мантиссой с большим порядком (ВП); сложение мантисс (СМ); нормализация результата (НР). В соответствии с этим в составе процессора предусмотрены четыре операционных блока, соединенных последовательно и реализующих четыре вышеперечисленных шага операции сложения: блоки СП, ВП, СМ и НР (рис. 2.2). Примем, что время выполнения каждого шага равно соответственно 60, 100, 140, 100 нс. Таким образом, операция сложения будет выполняться последовательностью операционных блоков за время 400 нс.
Далее предположим, что возникает задача сложения двух векторов А и В, содержащих по и элементов с плавающей запятой. Очевидно, для решения этой задачи потребуется сложить два числа:
Выполним эти операции на процессоре, организовав обработку данных следующим образом. После того как блок СП выполнит свою часть операции над первой парой операндов, он передает результат в следующий блок – ВП, а в блок СП будет загружена очередная пара операндов. На следующем шаге блок ВП передает результат выполнения своей части операции в блок СМ и начнет обрабатывать вторую пару операндов и т. д. Для того чтобы не создавались очереди операндов на обработку, примем, что время выполнения каждого из этих этапов одинаково и равно максимальному значению нс. В результате получим конвейер из четырех операционных блоков. Первый результат на выходе конвейера будет получен через 140X4 = 560 нс, т. е. несколько позже, чем если бы время выполнения всех этапов не выравнивалось. Однако все последующие результаты будут выдаваться через каждые 140 нc.
На рис. 2.2, б представлена временная диаграмма процесса. Общее время сложения двух векторов с помощью описанного конвейера, где т – число операционных блоков. Если бы конвейер не использовался, то это время было бы равно где – время выполнения i-го этапа обработки. Если применить конвейерную обработку к векторам, состоящим из 25 элементов, то получим ТК= (25 + 4– 1) • 140 = 3920 нc, Т0 = 25 • 400 = 10 000 нс.
Нетрудно заметить, что чем длиннее цепочка данных и чем на большее число этапов (а следовательно, и операционных блоков) разбивается операция (при той же длительности ее выполнения), тем больший эффект от использования конвейера может быть получен.
В приведенном выше примере было рассмотрено конвейерное выполнение арифметических операций, но идея конвейера может быть распространена и на выполнение команд. Надо сказать, что конвейер команд применяется уже давно в обычных ЭВМ.