Разрывая слово на x86 - PullRequest
       57

Разрывая слово на x86

10 голосов
/ 22 октября 2009

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

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

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

Ответы [ 3 ]

10 голосов
/ 22 октября 2009

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

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

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

1 голос
/ 30 октября 2009

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

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

1 голос
/ 22 октября 2009

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

...