Документ взят из кэша поисковой машины. Адрес
оригинального документа
: http://fpga.parallel.ru/Summ2/
Дата изменения: Tue Sep 14 18:27:35 2010 Дата индексирования: Mon Oct 1 19:52:49 2012 Кодировка: koi8-r |
КОМПЬЮТЕРЫ |
Неискушённый в параллельном программировании читатель может быть удивлён тем, насколько простая задача выбрана для разбора.
Однако, во-первых, уже те студенты, что изучали математические основы распараллеливания на самом простом уровне, знают, что задача суммирования элементов массива является прекрасной моделью для распространения приёмов, используемых на ней, на другие, более сложные задачи. Ассоциативность операции скалярного сложения, позволяющая нам при конструировании алгоритма суммирования использовать различный порядок для получения ускорения, является общим свойством также и многих других операций (скалярного умножения, матричных сложения и умножения), что позволяет распараллеливать, казалось бы, такие нераспараллеливаемые последовательные методы, как схемы Горнера и прогонки. Поэтому если мы научимся эффективно суммировать массивы, то этим также сделаем большой шаг к эффективной реализации на этой вычислительной архитектуре и более сложных методов.
Во-вторых, не надо забывать о том, что специфические для различных архитектур задачи, возникающие при адаптации программ к этой архитектуре, удобнее всего рассмотреть именно на примере простых программ. А даже для простой программы важно прежде всего знать её теоретические основы.
Суммирование элементов прямоугольного массива допускает много вариантов решения, что связано с ассоциативностью основной элементарной операции (суммирования двух элементов) в идеальном исчислении. В реальном исчислении (на устройствах с ограниченной мантиссой в числах вещественного типа), естественно, ассоциативности нет, и анализ влияния ошибок округления должен проводиться для каждого варианта в отдельности.
В этом варианте для накопления суммы используется один-единственный дополнительный вещественный элемент. На Фортране 77 соответствующая подпрограмма-функция будет выглядеть так:
real function SEQSUM(A,N,M)
При этом даже здесь есть возможность в представленном тексте, который реализует последовательное
суммирование по строкам (см. схему алгоритма ниже, синим показаны элементарные сложения),
переставить местами циклы и получить последовательное суммирование по столбцам:
Ясно, что в обоих случаях ни о каком параллелизме речи быть не может. Критический путь 1 графа будет равен NM+1 (на графе не показано первоначальное присвоение нуля переменной S).
В этом варианте для каждого из столбцов сумма накапливается отдельно, а потом эти полученные частные суммы прибавляются к общему "накопителю". На Фортране 77 соответствующая подпрограмма-функция будет выглядеть так:
real function COLSUM(A,N,M)И синими, и зелёными обозначены элементарные операции сложения чисел. В даном графе алгоритма, как и ранее, мы опустили передачи начальных данных и инициализации временных переменных. Как видно, общее количество элементарных операций увеличилось на M, но при этом критический путь 1 графа уменьшился до N+M+2, так что вполне возможны параллельные реализации. Например, можно реализовать параллельно внутренний цикл в представленной функции. Не следует, однако, забывать, что тогда мало будет одной накопительной переменной R на все циклы, и надо будет её размножить в массив.
Последовательные ветви (как в двух полностью последовательных вариантах, так и в последовательно-иерархическом) могут быть заменены на пирамиду. Наибольшую быстроту при таком распараллеливании даёт пирамида сдваиванием. Её, однако, редко записывают на последовательных языках, поскольку применяется-то сдваивание для распараллеливания.Если всё же записывают, то чаще с помощью рекурсивных вызовов, что не очень удобно для анализа графа. Причина - в том, что промежуточные результаты при нерекурсивной реализации надо хранить, и для этого нуже массив всего вдвое меньший, чем суммируемый. Рассмотрим подпрограмму пирамидного суммирования одномерного массива на Фортране 77 (простенький вариант для N, являющегося степенью двойки):
real function PIRSUM(A,B,N, L)Дадим её схему для суммирования 8 элементов на рисунке:
Здесь, как и ранее, синим цветом обозначены элементарные сложения, а чёрными стрелками - дуги графа алгоритма. Красным обозначены начальные данные (элементы массива) и их передача соответствующим вершинам графа алгоритма. Что хорошо в пирамиде сдваивания, это то, что в ней нет лишних элементарных сложений, и при этом имено она даёт минимальный критический путь 1 графа алгоритма.
Теперь рассмотрим рекурсивный вариант программы (на Си), но уже для произвольного N:
double PIRSUM(a,N)Её схема при равных N аналогична схеме предыдущей подпрограммы. Однако, при использовании такой схемы для гигантских N рекурсия всё же нежелательна, поскольку при большой глубине вызовов подпрограмм может переполниться стек, который часто используют для хранения параметров вызова во многих трансляторах.
Сложные каскадные схемы суммирования прямоугольного массива предполагают замену такой вот пирамидой последовательных участков (как синих, так и зелёных) предыдущей иерархически-последовательной схемы.
1Критическим путём в ациклическом ориентированном графе (коим является граф алгоритма) называется самый длинный из путей. Здесь мы считаем его по количеству вершин на пути.
Мы видели в предыдущем разделе, что даже для такой, на первый взгляд, простой математической операции может быть очень много разных реализаций. Следует, однако, помнить, что такое многообразие схем объясняется использованием ассоциативности операции сложения. Это свойство, однако, не является справедливым для машинных реальных операций сложения. Из-за этого при использовании разных алгоритмов суммирования у использующего получатся разные ошибки округления. Этот факт необходимо помнить, особенно когда такие суммирования используются внутри других алгоритмов как малые составные части, поскольку разный порядок совершения операций может стать причиной неустойчивости, если был реструктурирован даже изначально устойчивый алгоритм.
Если суммирование является самостоятельной частью алгоритма, а не входит существенным образом в другие операции (например, векторные, матричные), то с точки зрения минимизации ошибок округления в среднем выгоднее применять пирамидальное суммирование сдваиванием. Это, однако, никак не сказывается на теоретических оценках максимума ошибок результата - для каждого вида суммирования можно найти такое распределение, которое будет получать наибольшую ошибку именно для этого вида.
Помимо общих слов о том, что ряд библиотек пакетов, предназначенных для параллельной реализации, содержит специальные подпрограммы суммирования, остановимся на двух примерах реализаций: под средой MPI, предназначенной для кластерной архитектуры, и на языке Colamo (для ПЛИСов). Упомянем только, что суммирование не очень хорошо ложится на конвейерную архитектуру, на которой, пожалуй, самой быстрой будет векторная реализация иерархически-последовательных схем.
Но главное - то, что даже в отношении указанных 4 операций (*, +, max, min) опытные программисты под MPI с помощью умелого группирования выполняют масовые суммирования (умножения и др.) без использования этих двух подпрограмм не медленнее, а даже несколько быстрее, чем с их использованием.
При реализации на языке Коламо для ПЛИСов важен такой вопрос, как планирование ресурсов, которые будут отведены на реализацию задачи. В качестве примера приведём программу, реализующую пирамидально-конвейерную схему с использованием 16 сумматоров:
Program Piramida_Summatorov;Эта программа реализует каскадно-пирамидальную схему с использованием конвейеризации. Более детально вопросы программирования на Коламо при применении различных схем суммирования (по материалам семинара НИИ МВС при ТРТУ) будут рассмотрены в отдельном месте.
Итак, мы видим, что даже для простейших задач разных алгоритмических реализаций может быть уйма. Это, собственно, и объясняет то, что ими продолжают и продолжают заниматься исследователи, особенно когда приходится адаптировать задачу на новой вычислительной архитектуре и потому выбирать из множества реализаций ту, что лучше всех подойдёт для отображения на эту архитектуру.
ї Лаборатория Параллельных
информационных технологий НИВЦ МГУ