Введение
В информатике параллельный алгоритм, в отличие от традиционного последовательного алгоритма, – это алгоритм, способный выполнять несколько операций за заданное время. В компьютерной науке сложилась традиция описывать последовательные алгоритмы в абстрактных моделях машин, часто в модели машины с произвольным доступом к памяти. Аналогично, многие исследователи в области компьютерных наук использовали так называемую параллельную машину с произвольным доступом к памяти (PRAM) в качестве параллельной абстрактной машины (с общей памятью). Многие параллельные алгоритмы выполняются одновременно – хотя, в общем случае, параллельные и конкурентные алгоритмы представляют собой различные концепции – и поэтому эти понятия часто смешиваются, неясно разграничивая, какая часть алгоритма является параллельной, а какая – конкурентной. Более того, алгоритмы, не являющиеся ни параллельными, ни конкурентными, часто называют "последовательными алгоритмами" в отличие от конкурентных алгоритмов.
Параллельность
Алгоритмы значительно различаются по степени распараллеливаемости – от легко распараллеливаемых до полностью нераспараллеливаемых. Более того, для одной и той же задачи могут существовать различные алгоритмы, которые в разной степени поддаются распараллеливанию. Некоторые задачи легко разбиваются на независимые части – такие задачи называют тривиально распараллеливаемыми. Примерами служат многие алгоритмы для решения кубика Рубика и поиска значений, дающих заданный хеш. Другие задачи нельзя разделить на параллельные части, поскольку для эффективного выполнения следующего шага им требуются результаты предыдущего – такие задачи называются последовательными по своей природе. Примерами являются итеративные численные методы, такие как метод Ньютона, итеративные решения задачи трех тел и большинство известных алгоритмов для вычисления числа пи (π). Некоторые последовательные алгоритмы можно преобразовать в параллельные с помощью автоматической параллелизации.
Мотивация
Параллельные алгоритмы на отдельных устройствах стали более распространёнными с начала 2000-х годов благодаря существенным улучшениям в многопроцессорных системах и развитию многоядерных процессоров. До конца 2004 года производительность одноядерных процессоров быстро росла за счёт увеличения тактовой частоты, и поэтому было проще создать компьютер с одним быстрым ядром, чем с множеством медленных ядер с той же пропускной способностью, что ограничивало применение многоядерных систем. Однако, начиная с 2004 года, увеличение тактовой частоты столкнулось с ограничениями, и многоядерные системы получили более широкое распространение, сделав параллельные алгоритмы более востребованными.
Сообщение
Стоимость или сложность последовательных алгоритмов оценивается с точки зрения занимаемой ими памяти и времени (тактов процессора). Параллельные алгоритмы должны оптимизировать еще один ресурс – обмен данными между различными процессорами. Параллельные процессоры могут обмениваться данными двумя способами: через общую память или посредством передачи сообщений. Использование общей памяти требует дополнительной блокировки данных, создает накладные расходы на дополнительные процессорные и шинные циклы, а также приводит к последовательному выполнению части алгоритма. Передача сообщений использует каналы и буферы сообщений, но этот обмен данными добавляет накладные расходы на передачу по шине, требует дополнительной памяти для очередей и буферов сообщений, а также вносит задержку в обмен данными. В конструкциях параллельных процессоров используются специальные шины, такие как кроссбар, для минимизации накладных расходов на связь, однако именно параллельный алгоритм определяет объем трафика. Если накладные расходы на связь, связанные с добавлением дополнительных процессоров, превышают выигрыш от их использования, возникает эффект замедления параллельного выполнения.
Балансировка нагрузки
Другая проблема с параллельными алгоритмами заключается в обеспечении их надлежащего баланса нагрузки, то есть балансировки объёма работы (общей вычислительной нагрузки), а не размера входных данных. Например, проверку всех чисел от одного до ста тысяч на простоту легко распределить между процессорами; однако, если числа просто разделить поровну (от 1 до 1000, от 1001 до 2000 и т.д.), объём работы будет несбалансированным, поскольку меньшие числа легче обрабатывать с помощью этого алгоритма (проще проверять на простоту), и, следовательно, некоторые процессоры будут загружены больше, чем другие, которые будут простаивать до завершения работы наиболее загруженных процессоров.
Распределенные алгоритмы
Распределенные алгоритмы, являясь подтипом параллельных алгоритмов, – это алгоритмы, разработанные для работы в средах кластерных и распределенных вычислений, где необходимо учитывать дополнительные факторы, не рассматриваемые в "классических" параллельных алгоритмах.