Вызывает ли запись в область памяти из нескольких потоков конфликт? - PullRequest
0 голосов
/ 28 февраля 2019

Допустим, у меня есть непрерывный раздел памяти с адресами от 0 до 128, и аккуратно разделить его пополам, чтобы 6 потоков работали на каждом шестом байте, поток 1 получает 0, 6, 12, 18..., поток 2 получает 1, 7, 13, 19... и т. Д.

Если эти потоки пишут в эти байты, это заставит ЦП пытаться синхронизировать кеши по каждому ядру, потому что они локальны друг для друга?Что если каждый байт доступен как std::atomic<uint8>?

1 Ответ

0 голосов
/ 28 февраля 2019

Я не знаю обо всех процессорах, так как я больше всего знаком с 64-битным процессором Intel.Хотя в целом я бы сказал ДА, если хотя бы один поток будет записывать в память.

Все это связано со строками кэша.На моем ПК строка кэша составляет 64 байта (не бит), число, которое вы можете получить с помощью std :: hardware_destructive_interference_size .

. Если вы проигнорируете это, вы попадете в ловушку, которая называется:ложный обмен.Это аннулирование строки кэша, которую вы используете при записи в несвязанное значение в той же строке кэша.

Вы можете использовать std :: memory_order , чтобы предотвратить это, однако,значение является минимальным требованием, которое в Intel 64bit игнорируется в большинстве случаев, поскольку сам процессор гарантирует std :: memory_order_seq_cst.Это все еще может повлиять на оптимизацию.(Для небольших проходов оптимизации, которые могут иметь дело с атомами)

В заключение: выделите из потоков области памяти из случайных элементов, когда это возможно.

...