Вопрос

При каких обстоятельствах небезопасно иметь два разных потока, одновременно выполняющих запись в смежные элементы одного и того же массива в 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-разрядный доступ к кэшированной памяти внутри строки кэша является атомарным.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top