10

При каких обстоятельствах небезопасно иметь два разных потока одновременно для смежных элементов одного массива на x86? Я понимаю, что на некоторых DS9K-подобных архитектурах с безумными моделями памяти это может привести к разрыву слова, но на x86 однобайты адресуются. Например, на языке программирования D real представляет собой 80-битный тип с плавающей точкой на x86. Будет ли это безопасно сделать что-то вроде:Word Tearing on x86

real[] nums = new real[4]; // Assume new returns a 16-byte aligned block. 
foreach(i; 0..4) { 
    // Create a new thread and have it do stuff and 
    // write results to index i of nums. 
} 

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

Редактировать: Не беспокойтесь о том, чтобы прочитать записанные значения. Предполагается, что будет быть синхронизированным до считывания любых значений. Я забочусь только о безопасности , написав таким образом.

+0

Я предполагаю, что вы смотрите на грязные записи о смежных адресах? – BCS

ответ

10

x86 имеет последовательные кеши. Последний процессор для записи в строку кэша получает все это и записывает в кеш. Это гарантирует, что однобайтовые и 4 байтовые значения, записанные на соответствующие значения, будут автоматически обновляться.

Это отличается от его безопасности. Если процессоры каждый только записывают в байты/DWORDS «принадлежащие» этим процессором по дизайну, то обновления будут правильными. На практике вы хотите, чтобы один процессор считывал значения, написанные другими, и для этого требуется синхронизация .

Он также отличается от «эффективного». Если несколько процессоров могут писать в разные места в строке кэша, линия кэша может пинг-понг между процессорами, и это намного дороже, чем если бы линия кэша попала в один процессор и осталась там. Обычным правилом является размещение данных, специфичных для процессора, в собственной строке кеша. Конечно, если вы только собираетесь писать только одно слово, только один раз и , то объем работы значителен по сравнению с перемещением кэш-строки, тогда ваше исполнение будет приемлемым.

+0

Что касается вашей точки зрения на чтение: идея заключалась в том, чтобы параллельно массировать массив, используя параллельную карту. Функция отображения займет большую часть времени, так что время, затрачиваемое на запись, пренебрежимо мало, и строки кэша будут использоваться только в пределах границ рабочих единиц. Прежде чем какие-либо значения будут прочитаны из этого массива, будет использована синхронизация некоторого типа. – dsimcha

1

Возможно, у меня что-то не хватает, но я не предвижу никаких проблем. Архитектура x86 записывает только то, что ей нужно, она не записывает за пределами указанных значений. Cache-snooping обрабатывает проблемы с кешем.

1

Вы спрашиваете о специфике x86, но ваш пример находится на каком-то высоком уровне. На ваш конкретный вопрос о D могут ответить только люди, которые написали компилятор, который вы используете, или, возможно, спецификацию языка D. Например, Java требует, чтобы доступ к элементу массива не вызывал разрыва.

Что касается x86, то атомичность операций указана в разделе 8.1 из Intel's Software Developer's Manual Volume 3A. В соответствии с этим операции атомного хранилища включают в себя: сохранение байта, сохранение слова, выровненного по слову, и dword-aligned dword на всех процессорах x86. Он также указывает, что на процессорах P6 и более поздних версий 16-разрядный, 32- и 64-разрядный доступ к кэшированной памяти в строке кэша является атомарным.