Должны ли инструкции ARM ldrex/strex работать с данными, выровненными по кешу?

В Intel аргументы CMPXCHG должны быть выровнены по строке кэша (поскольку Intel использует MESI для реализации CAS).

На ARM ldrex и strex работают на эксклюзивных гранулах бронирования.

Чтобы было ясно, значит ли это, что в ARM данные, на которые нужно работать, не обязательно должны быть выровнены по строке кэша?

3 ответа

Решение

Об этом прямо говорится в Справочном руководстве по архитектуре ARM A.3.2.1 "Нераспределенный доступ к данным". LDREX а также STREX требует выравнивания слов. Что имеет смысл, потому что доступ к данным без выравнивания может охватывать гранулы эксклюзивного резервирования.

Эксклюзивные ограничения доступа

К исключительным доступам применяются следующие ограничения:

• Размер и длина эксклюзивной записи с заданным идентификатором должны быть такими же, как размер и длина предыдущего эксклюзивного чтения с тем же идентификатором.

• Адрес монопольного доступа должен соответствовать общему количеству байтов в транзакции.

• Адрес для эксклюзивного чтения и эксклюзивной записи должен совпадать.

• Поле ARID считываемой части эксклюзивного доступа должно соответствовать AWID записываемой части.

• Управляющие сигналы для частей чтения и записи эксклюзивного доступа должны быть идентичны.

• Количество байтов, подлежащих передаче в пакете исключительного доступа, должно быть степенью 2, то есть 1, 2, 4, 8, 16, 32, 64 или 128 байтов.

• Максимальное количество байтов, которое может быть передано в эксклюзивном пакете, составляет 128.

• Значение сигналов ARCACHE[3:0] или AWCACHE[3:0] должно гарантировать, что подчиненное устройство, отслеживающее монопольный доступ, увидит транзакцию. Например, эксклюзивный доступ, отслеживаемый ведомым устройством, не должен иметь значение ARCACHE[3:0] или AWCACHE[3:0], которое указывает, что транзакция кэшируется.

Несоблюдение этих ограничений приводит к непредсказуемому поведению.

Выше приведено в спецификации AMBA/AXI. Вы обнаружите, что AWLOCK/ARLOCK игнорируется некоторыми поставщиками (то есть ldrex/strex не будет работать вне ядра). У меня есть некоторый код, который демонстрирует это, или, по крайней мере, будет, если вы найдете систему, которая не поддерживает эксклюзивный доступ.

https://github.com/dwelch67/raspberrypi/tree/master/extest

В зависимости от задачи и того, насколько вы хотите быть переносимым, вам может потребоваться предоставить решения swp и ldrex/strex, окруженные ifdefs, и / или использовать множество доступных регистров (во время выполнения), чтобы сообщить вам, какие инструкции поддерживаются или не поддерживаются ядром. ты бежишь дальше. (Вы можете обнаружить, что по крайней мере в одном случае ни swp, ни ldrex/strex не поддерживаются).

В Intel аргументы CMPXCHG НЕ нужно выравнивать в кеше. Попробуйте, вы увидите, что это работает.

Но вы правы: в кешируемой памяти Intel использует протокол кеша для реализации CMPXCHG. Таким образом, было бы разумно не помещать две независимые переменные синхронизации с высокой интенсивностью использования в одну и ту же строку кэша - потому что, если бы два процессора синхронизировались с использованием этих разных переменных, строки кэша могли бы перебегать взад и вперед. Но это точно такая же проблема, как и для любых данных: вам не нужно, чтобы разные процессоры одновременно записывали в одну и ту же строку кэша. Ложный обмен.

Но вы, конечно, не можете кэшировать блокировки выравнивания строк:

struct Foo {
  int data;
  Lock lock;
  int data_after;
};

Вы можете поставить разные блокировки в одну и ту же кешлайн:

struct Foo {
  int data;
  Lock read_lock;
  int data_between;
  Lock write_lock;
  int data_after;
};

Поскольку чтение и письмо имеют тенденцию быть взаимоисключающими, не может быть потерь;

Вы можете поставить разные блокировки в одну и ту же кешлайн:

struct Foo {
  int data;
  Lock read_lock;
  int data_between;
  Lock write_lock;
  int data_after;
};

Кстати, в не кэшированной памяти Intel не использует протокол отслеживания кэша для атомарных операций, таких как CMPXCHG. Таким образом, есть меньше причин для кэширования строчных переменных синхронизации. Но вы все еще можете захотеть: многие подсистемы памяти чередуются по размеру кэша, даже когда не кэшированы.

А что касается ARM: это почти то же самое.

На снупи-шине или без кеширования вам, возможно, не нужно слишком беспокоиться о выравнивании строк кэша.

Но в иерархии кластерного кэша у вас точно такие же проблемы, как у x86. Более того, на самом деле хорошо известно, как "экспортировать" такие операции, как CMPXCHG, но не ARM ldrexd/strexd.

Другие вопросы по тегам