Разрыв слова на 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-разрядный доступ к кэшированной памяти в строке кэша является атомарным.