Задав еще один вопрос о алгоритме MapReduce, я подумал о том, как определить наиболее эффективный способ достижения общей суммы n значений с помощью параллельной обработки. Проблема может быть упрощена следующим образом:Как определить наиболее эффективный алгоритм параллельного добавления?
Предположим, что у меня есть n процессоров, каждая из которых имеет целое число. Я хочу как можно быстрее определить сумму целых чисел.
Теперь я мог бы получить каждый процессор 2, .., n, чтобы передать его целое число в процессор 1. Затем процессор 1 затем добавляет каждое из чисел, чтобы получить результат. Это означает, что n - 1 проход данных, но все это может происходить параллельно. За этим следуют n-1 операции сложения, происходящие последовательно.
В качестве альтернативы, я мог бы получить, чтобы каждый нечетный нумерованный процессор передавал свое целое число на следующий ровно пронумерованный процессор (предположим, что n является четным, для аргумента). Каждый четный процессор затем выполняет одну операцию добавления параллельно, добавляя свой номер к тому, который был только что передан. Затем мы заканчиваем добавлением 1/2 n целых чисел. Затем мы могли бы использовать предыдущий метод для добавления оставшихся значений.
Конечно, есть много других способов сделать это. Как определить, какая из них наиболее эффективна? Я подозреваю, что это зависит от относительной стоимости операции добавления и передачи целого числа (в реальной жизни, думаю, CPU против скорости сети) и, вероятно, также от размера n. В конце концов, если n очень велико, то добавление дополнительного сетевого хопа для сокращения вдвое n может стоить того, даже если каждое добавление относительно дешево.
X + Y + Z = (X xor Y xor Z) + ((X & Y) | (X & Z) | (Z & Y)) * 2 –
В некоторых случаях можно одновременно добавить несколько номеров одновременно более эффективно, чем попарно. Рассмотрим формулу: X + Y + Z = (X xor Y xor Z) + ((X & Y) | (X & Z) | (Z & Y)) * 2 Показывает, как преобразовать добавление трех чисел в дополнение к два номера, не вытягивая бит «carry» по всему номеру. –