Запись в смежные элементы массива из разных потоков? - PullRequest
8 голосов
/ 21 марта 2011

Существуют ли современные распространенные процессоры, в которых небезопасно записывать данные в смежные элементы массива одновременно из разных потоков? Я особенно заинтересован в x86. Вы можете предположить, что компилятор не делает ничего явно нелепого для увеличения степени детализации памяти, даже если это технически в рамках стандарта.

Меня интересует случай написания произвольно больших структур, а не только нативных типов.

Примечание:

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

Пояснение: эта проблема возникла из-за того, что на некоторых процессорах (например, старых DEC Alphas) ​​память может быть адресована только на уровне слов. Следовательно, запись в память с шагом, не равным размеру слова (например, в единичных байтах), на самом деле включала чтение-изменение-запись байта, который нужно записать , плюс несколько смежных байтов под капотом. Чтобы визуализировать это, подумайте о том, что входит в запись в одиночку. Вы читаете байт или слово, выполняете побитовую операцию над всем этим, а затем записываете все обратно. Поэтому вы не можете безопасно записывать в смежные биты одновременно из разных потоков.

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

Еще одно редактирование: Вот хороший справочник, который описывает проблему, о которой я говорю:

http://my.safaribooksonline.com/book/programming/java/0321246780/threads-and-locks/ch17lev1sec6

Ответы [ 2 ]

1 голос
/ 21 марта 2011

Да, безусловно, написание неправильно выровненного слова, которое пересекает границу строки кэша ЦП, не является атомарным.

1 голос
/ 21 марта 2011

Запись значения собственного размера (то есть 1, 2, 4 или 8 байтов) является атомарной (ну, 8 байтов является только атомарной на 64-битных машинах). Так что нет. Написание нативного типа всегда будет писать как положено.

Если вы пишете несколько собственных типов (т. Е. Зацикливаетесь на записи массива), возможно, будет ошибка, если есть ошибка в ядре операционной системы или обработчик прерываний, который не сохраняет требуемые регистры.

...