Урок 23: Атомарные операции: atomicAdd и гистограммы
Когда тысячи threads пытаются одновременно обновить одну и ту же ячейку памяти, возникает состояние гонки (race condition). Возьмём гистограмму: каждый thread читает значение и хочет увеличить счётчик bins[v] на единицу. Операция bins[v]++ выглядит атомарной, но на самом деле это три отдельных шага:
Представьте общую банку для счёта. Без atomic два человека оба видят число 5, оба прибавляют 1 в уме и оба записывают 6 — но должно было получиться 7, так что один подсчёт потерян. atomic — это как позволить только одному человеку за раз держать банку, добавлять и ставить обратно — никто никому не мешает.
- состояние гонки (race condition)
- Когда две параллельные операции обращаются к одной и той же памяти и хотя бы одна выполняет запись, из-за чего результат зависит от произвольного порядка их выполнения.
- атомарная операция (atomic)
- Read-modify-write, который аппаратура выполняет как одну неделимую единицу — ни один другой thread не вклинивается посередине. Например, atomicAdd.
- read-modify-write
- Три шага ++: прочитать значение, изменить, записать обратно. При параллельном выполнении, без защиты, эти шаги переплетаются между threads.
- гистограмма
- Подсчёт того, сколько раз встречается каждое значение. Каждый thread увеличивает bins[v]; множеству threads на одном и том же bin требуется atomicAdd.