Я хочу манипулировать древовидной структурой данных с несколькими потоками и защищать каждый узел мьютексом.
Целевая архитектура имеет несколько сотен потоков и работает на (виртуальной) разделяемой памяти.
Если ЦП 1 получает блокировку на узле, которым он должен манипулировать, будет ли этот мьютекс изменения состояния активно сообщаться всем остальным ядрам или только по запросу?
Я бы предположил, что, как и все другие изменения общих переменных, изменения мьютекса записываются в основную память. Кэши других процессоров становятся недействительными и заменяются в зависимости от их политики. Доступ к значению мьютекса осуществляется другим процессором, только если он хочет заблокировать его или если его политика замены кэша загружает его из памяти.
Правильно ли это, или мьютексы обрабатываются по-разному и передаются немедленно или скрываются до запроса?
Я хотел бы избежать аннулирования сотен кэшей каждый раз, когда узел заблокирован. Этот вопрос указывает на то, что шина блокируется каждый раз, когда используется мьютекс, что, по-видимому, не является проблемой.
редактировать
Я спрашиваю о мьютексах C ++ 11, реализованных в GCC 4.8. (Насколько я знаю, компилятор Intel также использует библиотеки GCC для всего, что связано со спецификацией C ++ 11.)
Я беспокоюсь о накладных расходах больше, чем о правильности.
Все потоки, работающие на любом ядре, будут взаимодействовать с мьютексом, как и следовало ожидать. Вам не нужно предпринимать никаких специальных действий.
Вы можете разумно ожидать, что под крышками будут присутствовать некоторые ограждения памяти, но это деталь реализации, а не то, о чем вы обычно хотели бы беспокоиться.
примечание стороны: если вы можете полностью распараллелить ваш процесс (то есть один поток не зависит от данных, созданных другим), то вы можете обнаружить, что каждый поток имеет свой собственный копия данных (и, следовательно, вообще не требующих мьютексов) даст вам значительно улучшенную производительность.