Разрывая слово на x86
-
05-07-2019 - |
Вопрос
При каких обстоятельствах небезопасно иметь два разных потока, одновременно выполняющих запись в смежные элементы одного и того же массива в 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.
}
Примечание. Я знаю, что даже если это безопасно, иногда это может привести к ложным проблемам с общим доступом к кешу, что приведет к снижению производительности. Однако для случаев использования, которые я имею в виду, записи будут достаточно редкими, чтобы на практике это не имело значения.
Редактировать: не беспокойтесь о чтении записанных значений. Предполагается, что будет синхронизироваться до того, как будут прочитаны какие-либо значения. Меня заботит только безопасность письма .
Решение
В x86 есть согласованные кеши. Последний процессор, который записывает в строку кэша, получает все это и выполняет запись в кэш. Это гарантирует, что однобайтовые и 4-байтовые значения, записанные в соответствующих значениях, будут атомарно обновлены.
Это отличается от "его безопасного". Если каждый из процессоров записывает только в байты / DWORDS, "принадлежащий" этим процессором, тогда обновления будут правильными. На практике вы хотите, чтобы один процессор считывал значения, записанные другими, и это требует синхронизации. р>
Он также отличается от "эффективного". Если несколько процессоров могут писать в разные места в строке кэша, то строка кэша может пинг-понг между процессорами, и это намного дороже, чем если бы строка кэша уходила в один процессор и оставалась там. Обычное правило - помещать специфичные для процессора данные в собственную строку кэша. Конечно, если вы собираетесь написать только одно слово, только один раз, и объем работы является значительным по сравнению с перемещением строки кэша, то ваше выступление будет приемлемым.
Другие советы
Я могу что-то упустить, но я не предвижу никаких проблем. Архитектура x86 записывает только то, что ей нужно, она не записывает ничего, кроме указанных значений. Отслеживание кэша решает проблемы с кэшем.
Вы спрашиваете о специфике x86, но ваш пример написан на языке высокого уровня. На ваш конкретный вопрос о D могут ответить только те люди, которые написали используемый вами компилятор, или, возможно, спецификацию языка D. Java, например, требует, чтобы доступ к элементу массива не вызывал разрыв.
Что касается x86, атомарность операций указана в разделе 8.1 Руководства разработчика программного обеспечения Intel, том 3А. . Согласно этому, атомарные операции хранилища включают в себя: сохранение байта, сохранение слова с выравниванием по словам и слова с выравниванием по слову на всех процессорах x86. В нем также указывается, что на процессорах P6 и более поздних процессорах невыровненный 16-, 32- и 64-разрядный доступ к кэшированной памяти внутри строки кэша является атомарным.