Разрыв слова на x86
В каких обстоятельствах небезопасно иметь два разных потока, одновременно записывающих соседние элементы одного массива на x86? Я понимаю, что на некоторых DS9K-подобных архитектурах с безумными моделями памяти это может привести к разрыву слова, но на x86 однобайты адресуются. Например, на языке программирования D real
есть 80-разрядный тип с плавающей точкой на 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.
}
Примечание. Я знаю, что даже если это безопасно, это может иногда приводить к ложным проблемам с кэшем, что приводит к низкой производительности. Однако для случаев использования я имею в виду, что записи будут нечастыми, чтобы это не имело значения на практике.
Изменить: не беспокоиться о том, чтобы прочитать записанные значения. Предполагается, что синхронизация будет до считывания любых значений. Таким образом, я забочусь о безопасности записи.
Ответы
Ответ 1
x86 имеет последовательные кеши. Последний процессор для записи в строку кэша получает все это и записывает в кеш. Это гарантирует, что однобайтовые и 4 байтовые значения, записанные на соответствующих значениях, будут автоматически обновляться.
Это отличается от "безопасного". Если процессоры каждый только записывают в байты /DWORDS "принадлежащие" этим процессором по дизайну, то обновления будут правильными. На практике вы хотите, чтобы один процессор считывал значения, написанные другими, и это требует
синхронизации.
Он также отличается от "эффективного". Если несколько процессоров могут писать в разные места в строке кэша, линия кэша может пинг-понг между процессорами, и это намного дороже, чем если бы линия кэша переходила в один процессор и оставалась там.
Обычным правилом является размещение данных, специфичных для процессора, в собственной строке кеша.
Конечно, если вы только напишете только одному слову, только один раз и
объем работы значителен по сравнению с перемещением кэш-строки, затем
ваша производительность будет приемлемой.
Ответ 2
Возможно, что-то мне не хватает, но я не вижу никаких проблем. Архитектура x86 записывает только то, что ей нужно, она не записывает за пределами указанных значений. Cache-snooping обрабатывает проблемы с кешем.
Ответ 3
Вы задаете вопрос о спецификациях x86, но ваш пример находится на каком-то высоком уровне. На ваш конкретный вопрос о D могут ответить только люди, которые написали компилятор, который вы используете, или, возможно, спецификацию языка D. Например, Java требует, чтобы доступ к элементу массива не вызывал разрыва.
Что касается x86, то атомичность операций указана в разделе 8.1 Руководство разработчика Intel Software Volume 3A. В соответствии с этим операции атомного хранилища включают в себя: сохранение байта, сохранение слова, выровненного по слову, и dword-aligned dword на всех процессорах x86. Он также указывает, что на процессорах P6 и более поздних версиях 16-разрядный, 32- и 64-разрядный доступ к кэшированной памяти в строке кэша является атомарным.