Under construction!

URL данного справочника
emc.orgfree.com/RISC-V/hb


Навигатор

home My RISC-V home

индекс Индекс

Инструкции
расширения A
(атомарные операции)

handbook

RV32A

RV64A


Evgeny Eremin

Инструкции AMOSWAP.W и AMOSWAP.D

AMOSWAP.W rd, rs2, (rs1)
AMOSWAP.D rd, rs2, (rs1)

Набор команд: RV32A – с .W и RV64A – с .D

Формат: R

Операнды: rs1 – адрес памяти, rd и rs2 – регистры

Действие: rd := (rs1), (rs1) := rs2 (атомарно!), т.е. обменять местами значение в памяти по адресу в rs1 со значением в rs2; гарантируется, что на время выполнения инструкции все прочие обращения к памяти будут заблокированы

Примечания

  1. AMO = Atomic Memory Operation.
  2. Специальная команда для синхронизации потоков (организации критической секции). Альтернативой является использование пары инструкций LR и SC.
  3. Формально, видимо, ради общности, можно назначить в качестве rd регистр x0, но это лишено логического смысла: алгоритм синхронизации должен проверять считанное значение (см. пример 3). Есть ощущение, что занесение «старого» значения в rd вообще введено только ради данной инструкции, а во всех остальных команд с AMO является практически бесполезным «рудиментом».
  4. В 64-битном режиме в команде с .W при записи в регистр rd в 32-битном слове расширяется знак.
  5. Адрес памяти в rs1 должен быть выровнен в соответствии с разрядностью операнда (т.е. делиться без остатка на 4 для .W и на 8 для .D). При нарушении возникает исключительная ситуация (exception). Предполагается возможность работы с невыровненными данными при наличии специального расширения Zam (пока не детализированного).
  6. Общие правила для задания значений битов aq (acquire – захват) и rl (release – освобождение) остаются в силе, но логика синхронизации требует перед критической секцией писать AMOSWAP.W/D.AQ, а в конце ее - AMOSWAP.W/D.RL (см. примеры).
  7. Инструкции с .W отличаются от таковых с .D значением в поле func3 (2 или 3 соответственно). Остальной код совпадает.

Пример 1

Инструкция AMOSWAP.W x31, x7, (x11) атомарным образом читает в x31 содержимое 32-битного слова по адресу из x11, а вместо него записывает 32 младших бита регистра x7.
Код инструкции содержит следующие поля:

полеразрядностьсодержимоепримечание
func55 битов00001 всегда
aq1 бит0aq = 0
rl1 бит0rl = 0
rs25 битов00111x7
rs15 битов01011x11
func33 бита010 всегда
rd5 битов11111x31
opcode7 битов0101111 всегда

Итоговый код

00001 00 00111 01011 010 11111 01011112 = 08 75 AF AF16

Пример 2

Инструкции AMOSWAP.W.AQ x31, x7, (x11) и AMOSWAP.W.RL x31, x7, (x11) имеют коды 0C 75 AF AF и 0A 75 AF AF соответственно.

Пример 3

Создание критической секции с помощью команды AMOSWAP (общепринято, что 1 – секция занята, 0 – свободна; в a0 задан адрес памяти).

       li t0, 1 # константа занятия секции
again: lw t1, (a0)    # проверка, свободна ли секция
       bnez t1, again # повторять, если нет
       amoswap.w.aq t1, t0, (a0) # пытаемся занять секцию
       bnez t1, again # повторять, если не удалось (кто-то уже  успел занять!)
# ...
# Критическая секция (выполняется только одним потоком)
# ...
       amoswap.w.rl x0, x0, (a0) # освобождаем (заносим 0)

Забавно, что в некоторых источниках команды lw и bnez опускают. Логика работы при этом полностью сохраняется, но есть нюанс: вариант цикла ожидания с lw не применяет AMO. Возможно, это меньше «тормозит» общее выполнение?


Автор справочника - Евгений Александрович Еремин (Пермский государственный гуманитарно-педагогический университет). e_eremin@yahoo.com


Free Web Hosting