многопоточность с помощью std :: atomic <> - PullRequest
1 голос
/ 03 июля 2019

В приведенном ниже небольшом примере кода я не понимаю, что, когда поток начинает увеличивать счетчик, поток записывает адрес счетчика в кэш, который используется совместно с ядром, и блокирует счетчик в кэше до тех пор, пока этот потокзавершить запись в счетчике, но если другая попытка добавить +1 к этому счетчику между предыдущим потоком чтения и записи изменить, он увидит, что данные в кэше заблокированы, и что тогда?будет ли второй поток в спящем режиме или просто подождет, пока счетчик в кеше не станет разблокированным?*

1 Ответ

0 голосов
/ 04 июля 2019

«Блокировка кэша» - это просто ядро, задерживающее ответ на запрос MESI о недействительности или обмене.

Это не мьютекс или что-то еще, это то, что может сделать одно ядро, настроив способ использования существующего протокола MESI-когерентности кэша, который гарантирует, что кэш-память никогда не будет иметь конфликтующих значений для одного и того же адреса. Другие ядра не должны знать о «замке», они просто видят задержку в ответе на запрос о совместном использовании строки. (У которого не было никаких жестких сроков или ожидаемого времени ответа; оно варьируется в зависимости от конкуренции и от того, сколько других ядер также ожидают эксклюзивного доступа к линии, чтобы зафиксировать их хранилище или RMW.)

См. Может ли num ++ быть атомарным для 'int num'? для полной информации. (Возможно, это не дубликат, потому что он начинается с более широкой предпосылки и охватывает многое, что здесь не актуально.)

Модель памяти C ++ предполагает согласованную совместную память, и это, по сути, все многоядерные машины. Всегда (AFAIK) с некоторым вариантом протокола MESI кэш-когерентности.


будет ли второй поток спать?

Нет, это все на аппаратном уровне. ОС не знает, что ядро ​​остановлено в ожидании строки кэша.

Это очень похоже на обычную ошибку кэша, ожидая, когда данные поступят из DRAM, а не из другого ядра.

...