Параллельные вычисления
Distributed Shared Memory
Google TPU Pod v4 - 4096 TPU чипов с 256GB HBM каждый - образует единое адресное пространство через межсоединение ICI. Обучение GPT-4 на таком кластере требует именно DSM-абстракции: тензор разбивается, части живут на разных чипах, но код видит единый массив.
- **PyTorch DDP** - Distributed Data Parallel: каждый GPU имеет копию модели, AllReduce синхронизирует градиенты после backward - это eventual consistency в действии
- **NUMA-aware ML** - TensorFlow и PyTorch имеют NUMA-aware allocator: данные размещаются близко к GPU/CPU, который будет их обрабатывать
- **Apache Spark** - RDD (Resilient Distributed Dataset) - DSM абстракция для big data: программист видит единую коллекцию, система управляет партициями по кластеру
Consistency Models: спектр гарантий
Consistency model - это контракт между программистом и системой памяти. Он определяет, в каком порядке операции записи становятся видны другим процессорам. Чем строже гарантии - тем медленнее система. Это фундаментальный trade-off.
Sequential Consistency (Lamport, 1979) - самая используемая строгая модель. Результат параллельного исполнения совпадает с каким-то последовательным чередованием операций. Java volatile и C++ std::atomic с memory_order_seq_cst дают SC-гарантии.
Pytorch распределённое обучение (DDP) использует eventual consistency для gradient aggregation через AllReduce. Строгой консистентности нет - и это нормально: forward pass к следующей итерации ждёт завершения AllReduce. Consistency model подбирается под семантику задачи.
Что гарантирует Sequential Consistency?
Distributed Shared Memory: единое адресное пространство
DSM - система, которая даёт программисту иллюзию общей памяти, хотя физически данные распределены по разным машинам. Процесс обращается к адресу - и не знает, находятся ли данные локально или за сетью. Это software illusion поверх distributed hardware.
Page-based DSM (IVY, TreadMarks): единица разделения - страница памяти (обычно 4KB). При промахе - page fault → сетевой запрос к владельцу страницы → передача данных. False sharing: два процесса используют разные переменные на одной странице - и постоянно друг другу мешают.
NUMA - это современный mainstream: все серверные x86 и ARM CPU NUMA-aware. numactl и taskset позволяют привязывать процессы к NUMA-узлам. Неправильная NUMA-локализация - типичная причина неожиданных производительностных провалов в ML-training на многосокетных серверах.
Что такое false sharing в контексте DSM?
Репликация: надёжность через избыточность
Репликация в DSM решает две задачи: fault tolerance (данные не потеряются при сбое узла) и read throughput (несколько узлов могут читать одновременно). Но каждая запись должна распространиться на все реплики - и здесь возникает CAP-теорема.
Primary-backup: один узел (primary) принимает записи, реплицирует на backup. При сбое primary - backup становится новым primary. Redis Sentinel, PostgreSQL streaming replication. Простая схема, но primary - узкое место для writes.
Cassandra и DynamoDB используют quorum replication без единого лидера. Replication factor R, write quorum W, read quorum Q. При W + Q > R гарантирован overlap - хотя бы один узел в read quorum видел последнюю запись. Типичная конфигурация: R=3, W=2, Q=2.
Минимальный кворум для чтения в Cassandra при R=5, W=3?
Протоколы когерентности: MSI, MESI, MOESI
Cache coherence - задача поддержания консистентности кэшей разных CPU. Без протокола когерентности: CPU 0 читает X=0, кэширует. CPU 1 пишет X=1. CPU 0 читает X - получает устаревший 0 из кэша. Это катастрофа для корректности программы.
MESI протокол: кэш-линия имеет 4 состояния. Modified (грязная, только у меня), Exclusive (чистая, только у меня), Shared (чистая, у нескольких), Invalid (устаревшая). При записи: переход в Modified + отправка Invalidate всем, у кого Shared копия.
Directory-based coherence (vs snooping): при большом числе CPU каждый broadcast Invalidate - дорого. Directory хранит список узлов с копиями каждой линии. Invalidate отправляется точечно. AMD EPYC и Intel Xeon Scalable используют directory-based когерентность для кросс-NUMA трафика.
Distributed Shared Memory даёт такую же производительность, как локальная память
DSM - это программная абстракция поверх медленной сети; latency между узлами в 10-100x выше локального RAM
Скрытие сети за абстракцией удобно для программирования, но не меняет физику. Locality-aware programming (правильная привязка данных к вычислениям) критична для производительности DSM и NUMA систем
Что происходит с кэш-линией в состоянии Shared при попытке записи?
Связанные темы
DSM связывает архитектуру памяти с распределёнными системами:
- Memory Ordering и барьеры — Физическая основа consistency models
- MapReduce и Spark — Альтернативный подход: computation locality вместо memory sharing
- SIMD и векторизация — NUMA-aware SIMD - следующий уровень оптимизации
Ключевые идеи
- **Consistency models** - контракт о порядке видимости записей; строже = медленнее, слабее = масштабируемее
- **DSM** даёт иллюзию единой памяти поверх distributed hardware; false sharing - скрытый performance killer при малой грануляции
- **Репликация** решает fault tolerance и read throughput; CAP теорема ограничивает что можно гарантировать одновременно
- **MESI протокол** обеспечивает когерентность кэшей: Invalidate при записи в Shared гарантирует что все увидят новое значение
Вопросы для размышления
- Почему Google перешёл от MapReduce к более memory-sharing подходам в новых системах (Dataflow, Flume)?
- Как выбор consistency model влияет на возможность horizontal scaling распределённой системы?
- MESI работает хорошо для небольшого числа CPU. Почему directory-based протоколы необходимы при сотнях узлов?
Связанные уроки
- par-05 — Shared Memory - основа, DSM обобщает её на сетевой уровень
- par-10 — Memory ordering и барьеры - фундамент consistency models
- par-14 — MapReduce решает другой аспект: computation, а не memory
- par-16 — SIMD и NUMA - физическая реализация иерархии памяти
- par-09 — Lock-free структуры данных реализуют часть consistency требований
- os-07-memory
- dist-03-fallacies