вершин на пути.
Ошибки округления при суммировании
Мы видели в предыдущем разделе, что даже для такой, на первый взгляд, простой математической операции может быть очень много разных реализаций. Следует, однако, помнить, что такое многообразие схем объясняется использованием ассоциативности операции сложения. Это свойство, однако, не является справедливым для машинных реальных операций сложения. Из-за этого при использовании разных алгоритмов суммирования у использующего получатся разные ошибки округления. Этот факт необходимо помнить, особенно когда такие суммирования используются внутри других алгоритмов как малые составные части, поскольку разный порядок совершения операций может стать причиной неустойчивости, если был реструктурирован даже изначально устойчивый алгоритм.
Если суммирование является самостоятельной частью алгоритма, а не входит существенным образом в другие операции (например, векторные, матричные), то с точки зрения минимизации ошибок округления в среднем выгоднее применять пирамидальное суммирование сдваиванием. Это, однако, никак не сказывается на теоретических оценках максимума ошибок результата - для каждого вида суммирования можно найти такое распределение, которое будет получать наибольшую ошибку именно для этого вида.
Реализация суммирования на некоторых параллельных вычислительных системах
Помимо общих слов о том, что ряд библиотек пакетов, предназначенных для параллельной реализации, содержит специальные подпрограммы суммирования, остановимся на двух примерах реализаций: под средой MPI, предназначенной для кластерной архитектуры, и на языке Colamo (для ПЛИСов). Упомянем только, что суммирование не очень хорошо ложится на конвейерную архитектуру, на которой, пожалуй, самой быстрой будет векторная реализация иерархически-последовательных схем.
Реализация под средой MPI
Программирующие в среде обмена сообщениями MPI, конечно, могут использовать вышеприведённые схемы суммирования массива, распределённого по секциям памяти разных узлов кластера, самостоятельно, с помощью подпрограмм пересылки сообщений. Однако сами такие сообщения окажутся (для любой из выбранных схем) очень короткими, что при недостаточном опыте программиста отрицательно скажется на производительности системы. Поэтому разработчики среды предусмотрели выполнение массовых операций с помощью специальных подпрограмм, в которых уже заложены пересылки, не самым худшим образом оптимизированные под среду. Это - две подпрограммы: MPI_Allreduce и MPI_Reduce. Различаются они только тем, что во второй подпрограмме результат получает только один из узлов MPI, а не все (как в первой). Что показательно, подпрограммы эти могут выполнять не только суммирование массива, но и три других массовых операции по всему массиву: вычисление минимума, максимума и произведения. Для тех читателей, что заинтересовались данной страницей о суммировании в связи с универсальностью его вычислительных схем, данная новость обладает двойственным характером. С одной стороны, для описанных простых операций это хорошо, и неопытные в MPI программисты могут пользоваться ими. Однако то, что в списке базовых операций для этих подпрограмм отсутствуют более сложные (скалярное произведение, матричное умножение и т.п.), означает, что для этих операций надо будет писать реализации описанных выше схем с помощью ручного программирования и программ пересылки сообщений. Что, однако, будет в отношении замедления производительности (как, впрочем, и для описанных четырёх операций) уже не таким критичным, поскольку при выполнении более сложных операций матричного типа длина сообщений существенно увеличится, а главное - увеличится ещё больше доля "арифметики" между межузловыми обменами данных.
Но главное - то, что даже в отношении указанных 4 операций (*, +, max, min) опытные программисты под MPI с помощью умелого группирования выполняют масовые суммирования (умножения и др.) без использования этих двух подпрограмм не медленнее, а даже несколько быстрее, чем с их использованием.
Do'stlaringiz bilan baham: |