1. 1

# конспект · шаг 1 из 1

Конспект раздела: параллельные и внешние алгоритмы

выжимка - её можно унести в заметки

Одна мысль на весь раздел

RAM-модель считает операции и предполагает, что они идут по одной и любая ячейка стоит единицу. Раздел шесть раз менял это предположение, и каждый раз менялось то, что считают: шаги и работа при многих процессорах, порядок операций при общей памяти, сообщения при сети, блоки при диске. Алгоритм, лучший в одной модели, бывает плохим в другой - поэтому первый вопрос к задаче: что здесь дорого?

Дерево решений

что дорого в задаче?
├── много исполнителей, общая память, счёт шагов
│   ├── сколько неизбежно последовательных шагов?  → глубина T∞
│   ├── сколько всего работы?                      → работа T₁
│   └── хватит ли ядер?  T₁/p против T∞; Брент: Tₚ ≤ T₁/p + T∞
├── исполнители пишут в одну память без общего такта
│   ├── хватит ли атомарной операции?  → fetch_add, CAS-цикл
│   ├── нужен замок?  → TTAS / талоны / MCS; общий порядок захвата
│   ├── что значит «правильно»?  → линеаризуемость, проверка истории
│   └── нельзя зависеть от медленного потока?  → lock-free / wait-free
├── узлы связаны сетью
│   ├── короткие сообщения → дерево, log₂ p задержек
│   ├── длинные данные → конвейер, кольцо: передача ≈ βn
│   └── неизвестные размеры задач → кража работы
└── данные больше памяти
    ├── читается подряд? → проход N/B
    ├── нужен поиск → B-дерево, log_B N
    ├── нужна сортировка → прогоны + слияние по M/B путей
    └── поток вставок → LSM-дерево

Как части связаны

величина где появляется чем её уменьшают
глубина PRAM, граф задач, скан, сети дерево вместо цепочки: log n вместо n
работа лишняя работа, порог, слияние рангами работоэффективные схемы, крупные задачи
число чередований гонка, замки атомарные операции, критическая секция
трафик кеша спин-блокировки, кеш ожидание чтением, своя ячейка, блоки
задержка α сообщения, all-reduce деревья, склейка мелких сообщений
передача β рассылка, all-reduce конвейер, кольцо, разбиение на куски
блок B диск, кеш, внешние структуры проходы, ветвление B, прогоны

Одна и та же идея повторяется в разных одеждах: дерево вместо цепочки (сумма деревом, скан, рассылка, B-дерево) и крупные порции вместо мелких (порог задачи, склейка сообщений, кольцо по кускам, прогоны, LSM).

Числа раздела, которые стоит помнить

сумма 1000 чисел деревом - 10 шагов; сборка: работа 44, глубина 22
слияние с обычным слиянием: параллелизм log₂ n / 2 (6 на 4096)
Амдал: 5% последовательного кода - потолок 20
скан Блеллоха: 2(n − 1) сложений; Хиллис - Стил: n log n
битонная сеть на 8 входов: 6 слоёв, 24 компаратора; минимум - 19
c = c + 1 двумя потоками: правильно в 2 чередованиях из 20
Петерсон: 26 состояний; на TSO без барьера - двое в секции
16 ядер: TAS ~47 обращений к шине на захват, TTAS ~33, MCS ~5
порог α / β = 200 КБ при α = 20 мкс и 10 ГБ/с
all-reduce 100 МБ на 64 узлах: кольцо 22 мс, гиперкуб 60
двоичный поиск на 10⁸ ключах - 18 блоков, B-дерево - 3
внешняя сортировка - один проход слияния, пока N ≤ M² / B

Границы, общие для всех результатов

Модели нарочно грубые: PRAM не знает про синхронизацию и кеши, перебор состояний верен только в моделируемой модели памяти, α + β · n не знает про перегрузку сети, а модель внешней памяти - про предвыборкуРазбирается в разделе 25, глава «Память, локальность и честный замер»: Иерархия памяти: одна и та же сумма в шесть раз медленнее и ассоциативность кеша. Модель отвечает на вопрос «какой алгоритм лучше и почему», точные числа даёт только замер - об этом следующий раздел.

Ловушки джокера

Делить работу на число ядер. Время не меньше глубины.

Малая глубина ценой работы. На восьми ядрах обычно решает работа, а не глубина: пока глубина много меньше работы, делённой на число ядер.

Гонку проверять тестами. Плохие чередования редки; протокол доказывают перебором состояний.

Перебор не в той модели памяти. На x86 протоколу из чтений и записей нужен барьер.

Ждать записью в общую ячейку. Трафик когерентности тормозит и ожидающих, и владельца.

Замки в разном порядке. Цикл ожидания и вечная взаимоблокировка.

Мелкие сообщения и один координатор. Задержки и узкое место; сбор - деревом.

Дерево для больших данных. Каждый раунд гонит весь объём; нужен конвейер или кольцо.

Случайный доступ к диску. В B раз дороже прохода; сортируют слиянием, ищут B-деревом.

Цена синхронизации и перемещения данных

Задача Инструмент Условие или граница
Ранг списка Независимое множество Ожидаемая работа O(n); сравнивай работу и глубину отдельно.
Ожидание условия Монитор и RW-lock wait проверяет предикат в while; предпочтение писателей не равно FIFO.
Конкурентные чтения Backoff и атомарный снимок Откат нагрузки не обещает справедливость; снимку нужны версии и помощь.
Три внешних файла Многофазное слияние Фибоначчи - выбранное расписание, а не единственная возможная раскладка.
Рёбра на диске Полувнешний Крускал DSU помещается в памяти; инициализация стоит Θ(n), сортировка оплачивается отдельно.

Проверь, что можешь объяснить

  1. Почему у суммы деревом параллелизм n / log n, а у сортировки слиянием с обычным слиянием - log n / 2?
  2. Почему жадный планировщик не хуже лучшего расписания больше чем вдвое?
  3. Как скан превращает упаковку массива в одновременную запись без очереди?
  4. Почему двух флагов мало для замка, а флага и жертвы - достаточно?
  5. Что ломает Петерсона на x86 и где ставить барьер?
  6. Чем линеаризуемость отличается от последовательной согласованности - на примере очереди?
  7. Почему цикл CAS - lock-free, но не wait-free?
  8. Когда all-reduce делают гиперкубом, а когда кольцом, и почему?
  9. Почему вор в краже работы берёт задачу из начала дека?
  10. Сколько проходов делает внешняя сортировка терабайта при 16 ГБ памяти, и почему не семь?
  11. Почему блок транспонирования 8 × 8 бывает не лучше обычного цикла?
  12. Почему LSM-дерево пишет каждый элемент много раз и всё же быстрее B-дерева на вставках?

Комментарии

Пока нет комментариев. Будь первым!

Оставить комментарий

Комментарий появится после проверки. Email не публикуется. Войти, чтобы не вводить имя каждый раз.