Under construction!

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


Навигатор

home My RISC-V home

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

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

handbook

RV32A

RV64A


Evgeny Eremin

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

LR.W rd, (rs1)
LR.D rd, (rs1)

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

Формат: R

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

Действие: rd := (rs1); «резервирует» прочитанные байты (4 при .W и 8 при .D) в памяти, контролируя последующий доступ к ним; позднее парная с ней операция SC.W/D проверит сохранность резервирования (т.е. чтобы значения в памяти за время между LR и SC не изменились другим потоком или устройством)

Примечания

  1. LR = Load-Reserved.
  2. Работает «в паре» с SC. Параметры 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

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

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

Итоговый код

00010 00 00000 01011 010 11111 01011112 = 10 05 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