Under construction!

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


Навигатор

home My RISC-V home

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

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

handbook

RV32A

RV64A


Evgeny Eremin

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

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

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

Формат: R

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

Действие: если зарезервированные ранее командой LR данные не были изменены, то rd := 0, (rs1) := rs2; иначе rd < > 0 и запись в память отменяется

Примечания

  1. SC = Store-Conditional.
  2. Работает «в паре» с LR. Параметры LR и SC (адрес, число байтов) должны совпадать.
  3. В 64-битном режиме в команде с .W при записи в регистр rd в 32-битном слове расширяется знак.
  4. Адрес памяти в rs1 должен быть выровнен в соответствии с разрядностью операнда (т.е. делиться без остатка на 4 для .W и на 8 для .D). При нарушении возникает исключительная ситуация (exception). Возможность работы с невыровненными данными не предполагается.
  5. Общие правила для задания значений битов aq (acquire – захват) и rl (release – освобождение) такие же, как и в остальных инструкциях расширения A. Но во всех (немногочисленных) имеющихся примерах используются только нулевые значения битов aq и rl – см. пример 2.
  6. Инструкции с .W отличаются от таковых с .D значением в поле func3 (2 или 3 соответственно). Остальной код совпадает.

Пример 1

Инструкция SC.W x31, x7, (x11) выполняет следующие действия. Сначала проверяет сохранность всех 4 байтов данных в ОЗУ с адреса из x11 (точнее говоря, факт отсутствия записи в них после LR). Затем устанавливает x31 = 0 при отсутствии изменений и ненулевое значение в противном случае. Только когда проверка была успешной и x31 = 0, содержимое младших 4 байт из x7 записывается в память, начиная с адреса из x11.
Код инструкции содержит следующие поля:

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

Итоговый код

00011 00 00111 01011 010 11111 01011112 = 18 75 AF AF16

Пример 2

Атомарная организация занятия ресурса с помощью пары команд LR/SC (как обычно, значение 1 – это занято, 0 – свободно; предполагается, что в x20 находится адрес памяти).

       addi x12, x0, 1	    # константу занятости 1 заносим в x12
again: lr.d x10, (x20)	    # считываем признак занятости для проверки
       bne x10, x0, again   # повторить, если кем-то уже занято (x10<>0)
       sc.d x11, x12, (x20) # пытаемся занять
       bne x11, x0, again   # повторить, если не удалось (x11<>0)
# ...
       sd x0, 0(x20)	    # освобождаем (заносим 0)

Пример 3

В известной книге Дэвида Паттерсона и Джона Хеннесси “Computer Organization and Design. The Hardware/Software Interface: RISC-V Edition” кроме приведенного выше примера 2 дана еще одна рекомендация по использованию пары LR/SC: между ними можно поместить несколько команд атомарной модификации прочитанного из памяти содержимого. Команд не должно быть много и допускаются не все инструкции, но так можно делать. Например, упомянуты примитивы синхронизации atomic compare and swap (CAS, близко к AMOSWAP) и atomic fetch-and-increment (полный аналог AMOADD).

Насколько я понимаю, следуя этой идее, атомарное увеличение счетчика можно написать так.

again: lr.d x6, (x10)	  # считываем значение из памяти
       addi x6, x6, 1	  # +1
       sc.d x7, x6, (x10) # пытаемся записать результат
       bne x7, x0, again  # повторять, если не удалось (x7<>0)

Хотя, конечно, вариант с AMOADD выглядит проще и привлекательнее.


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


Free Web Hosting