Барьеры памяти и большие структуры?

Допустим, у меня есть структура, состоящая из 100 байтов. Какие гарантии у меня есть по поводу следующего кода?

m_myLargeStruct = someValue; // copying 100 bytes
Thread.MemoryBarrier();

// Executed by another thread, after "Thread.MemoryBarrier" was called by the first thread
Console.WriteLine(m_myLargeStruct.ToString());

Гарантирует ли модель памяти, что 100-байтовая копия будет завершена после установки барьера памяти? или барьеры памяти применяются только к типам, размер которых не превышает размер архитектуры процессора? (4 байта для 32-битных и 8 байтов для 64-битных).
По этой ли причине ключевое слово volatile применяется только к примитивным типам? (если я объявляю 8-байтовый член как изменчивый, это означает, что для изменения его значения будет использоваться заблокированный экземпляр? [поскольку атомарность не гарантируется для типов размером более 4 байтов на 32-битных машинах]).

Надеюсь, я был достаточно ясен .. :)
Спасибо


person Community    schedule 13.11.2009    source источник


Ответы (5)


Ясно, что ответ нет, точнее, у вас нет никаких гарантий ни в чем. Ничто не мешает операционной системе заменить поток, который записывает 100-байтовую структуру, перед запуском потока, распечатывающего 100-байтовую структуру.

Барьер памяти используется, когда вы хотите координировать доступ к данным через флаг или другое атомарное значение. Я не знаю, что именно вы пытаетесь сделать, поэтому я не могу дать вам хороший пример кода о том, как вы должны это делать.

person MSN    schedule 14.11.2009
comment
После некоторого интенсивного чтения книги Даффи я понял, что весь этот вопрос возник из-за неправильного понимания с моей стороны, спасибо - person ; 14.11.2009

Если поток чтения также не имеет барьера памяти, я не думаю, что это вам сильно поможет.

Лично я бы избегал:

  • Такие большие конструкции
  • Глубокое погружение в модель памяти для написания кода без блокировок

... если у вас нет для этого действительно важной причины. Чрезвычайно трудно получить кодирование без блокировок с изменяемыми данными; Я считаю, что даже эксперты борются. Обычно я нахожу, что подход «блокировать каждый блок, обращающийся к данным» легче реализовать и он подходит с точки зрения производительности в 99% случаев.

Я верю команде PFX в Microsoft, чтобы получить правильное кодирование без блокировок, и чтобы они предоставили мне способы, которыми я могу использовать их код для относительно простого написания моих собственных программ без блокировок. Я не верю, что могу понять подобные вещи правильно. Если мне когда-нибудь понадобится явно использовать барьер памяти, это, вероятно, означает, что я слишком стараюсь.

person Jon Skeet    schedule 13.11.2009
comment
Простая аффинная матрица может быть примерно такого размера - и базовый фреймворк использует для этого структуры. Конечно, реализация структур не кажется отточенной, поэтому, если вы действительно не хотите писать код, который неявно работает с проблемами компилятора / CLR, вы вряд ли получите лучшую производительность. С другой стороны, для многих целей структуры имеют лучшую семантику, чем классы. Я вполне мог представить себе использование структур только для того, чтобы иметь красивую и простую семантику значений. - person Eamon Nerbonne; 13.11.2009
comment
@Eamon: вам не нужны структуры для получения семантики значений, вам просто нужен неизменяемый класс. Возьмем, к примеру, класс String. - person Guffa; 13.11.2009
comment
Я спрашиваю в более академическом смысле ... У меня действительно нет 100 байтов в качестве структуры. Я конкретно спрашиваю, что и как гарантируется. Этот вопрос не об общих передовых методах разработки программного обеспечения ... - person ; 13.11.2009
comment
@Jon Если поток чтения также не имеет барьера памяти - в этом случае у вас нет никаких гарантий - поскольку поток чтения может выполняться перед потоком записи (и даже без этого - барьеры памяти предотвращают переупорядочение с точки single нить не всю архитектуру). Ему явно нужна какая-то форма синхронизации (предпочтительно блокировка, если это не доказано обширным профилированием). - person Jan; 17.07.2014

Вам нужен еще один барьер памяти во втором потоке перед WriteLine. (Если ваша система предоставляет асимметричные барьеры памяти, достаточно выполнить барьер Release после назначения и барьер Acquire перед WriteLine).

Размер данных не имеет значения.

person atzz    schedule 13.11.2009
comment
знаете ли вы какие-нибудь статьи, которые должным образом объясняют это поведение? - person ; 14.11.2009
comment
Не навскидку ... хотя попробуйте это [niallryan.com/node/138] и это [ en.wikipedia.org/wiki/Memory_barrier]. - person atzz; 14.11.2009

Вам нужен барьер памяти в обоих местах / потоках, и, конечно, вам нужна какая-то синхронизация между ними, чтобы барьер второго потока не запускался перед первым потоком.

В частности, потоку записи требуется «освободить» барьер памяти, а потоку чтения нужен барьер «получения» памяти (если базовая платформа поддерживает семантику отдельного барьера).

Если вы не спрашиваете из академического любопытства или не пишете свой собственный фреймворк, вам действительно следует просто использовать объект синхронизации из библиотеки / фреймворка / платформы. Попытка исправить все это сложно, и это уже сделано в предоставленных объектах синхронизации.

person Michael Burr    schedule 13.11.2009

Во-первых, у вас не должно быть такой большой структуры. Если вы не будете предельно осторожны в использовании структуры, это будет медленнее, чем использование класса. Кроме того, это противоречит семантике значений структур.

Тем не менее, барьер памяти гарантирует, что структура будет скопирована. Оптимизация не приведет к перемещению каких-либо инструкций через барьер.

Ключевое слово volatile немного другое. Это гарантирует, что никакие операции с переменной не будут оптимизированы, и гарантирует порядок доступа к памяти. Однако для типов данных, к которым нельзя получить атомарный доступ, он в основном бесполезен для потоковой передачи, поскольку вы все равно можете прочитать половину нового значения и половину старого значения.

person Guffa    schedule 13.11.2009
comment
Нет, volatile действительно гарантирует заказ. Запись в изменчивую переменную имеет семантику выпуска, а чтение из одной имеет семантику получения IIRC. (Подробности см. В ECMA 335.) - person Jon Skeet; 13.11.2009