Эта информация касается возможностей по сниижению временных задержек путём расположения пар инструкций оптимальным образом:
STR Rx, [Rym #imm]
всегда выполняется за один цикл. Происходит это оттого, что генерация адреса осущесвтляется в инициализации цикла, а сохранение данных происходит прямо в тот-же самый цикл как исполнение следующей инструкции. Если сохраняемое находится в буфере сохранения и буфер полон или не разрешён к использованию в этот момент следующая инструкция будет задержана до тех пор, пока сохранение не будет завершено. Если сохранение идёт не через буфер, к примеру в сегмент Code и эта тарнзакция приостанавливается, влияние на время выполнения будет ощущаться лишь в случае если другая операция выгрузки или загрузки выполнялась перед завершением.
LDR Rx!, [any]
обычно не конвейеризуется. В связи с тем, что операция загрузки как минимум занимает два цикла (и больше, если была приостановлена). Следует иметь в виду, что если следующая инструкция не требует доступа к любому из регистров, то инструкция загрузки будет осуществлена за один цикл. Такие инструкции (не затрагивающие регистры) включают CMP
, TST
, NOP
и non-taken IT
управляющие инструкции.
LDR PC, [any]
всегда блокирующая операция. Она требует как минимум два цикла на выполнение и три для перезагрузки конвейера. В связи с этим, такая операция требует 5 циклов или даже больше если была приторможена операциями очистки буферов загрузки или выгрузки данных.
LDR Rx,[PC, #imm]
может добавть один цикл из-за конкуренции с модулем выборки.
TBB
и TBH
также блокирующие операции. Они требуют как минимум два цикла на загрузку, один для добавления и три для перезагрузки конвейера. Это подразумевает шесть циклов исполнения или даже больше если операция была приторможена из-за конкуренции с модулями загрузки/выгрузки.
LDR [any]
конвейеризуется всегда, когда возможно. Это означает, что если следующая инструкция будет либо LDR
, либо STR
и назначение в первом LDR
не используется для вычисления адреса следующей инструкции, тогда один цикл будет сокращён из времени выполнения. Обратите внимание, что LDR
может следовать за STR
также, как и STR
может записывать то, что было загружено LDR
. Последовательно идущие LDR
могут быть конвейеризированы. Пример такой оптимизации:
; займёт 3 цикла на выполнение обеих команд:
LDR R0, [R1];
LDR R1, [R2];
; займёт 3 цикла на выполнение обеих команд:
LDR R0, [R1,R2];
STR R0, [R3,#20];
; займёт 3 цикла на выполнение обеих команд:
LDR R0, [R1,R2];
STR R1, [R3,R2];
; займёт 4 цикла на выполнение всех команд:
LDR R0, [R1, R5];
LDR R1, [R2];
LDR R2, [R3,#4]
STR
с регистровым смещением. STR
может быть конвейеризирован только в том случае, если он следует за LDR
. Однако ничего не может быть помещено в конвейер после такой выгрузки. Даже приторможенный STR
обычно исполняется всего за два чикла, потому что результат выгрузки помещается в буфер.
LDREX
и STREX
могут быть конвейеризированы также точно как и LDR
. Поскольку STREX
вызывается, преимущественно, как LDR
он конвевйеризуется как объяснено для LDR
. Одинаково и LDREX
вызывается в точности также как и LDR
и ведёт себя аналогично.
LDRD
и STRD
не могут быть конвейеризированы с предыдущими или следующими за ними инструкциями. При этом, на самом деле, два слова конвейеризуются вместе. Поэтому такая операция занимает всего три цикла, если не была приторможена на блокировке буфера.
LDM
и STM
не могут быть конвейеризированы с предыдущими или следующими за ними инструкциями. При этом, все элементы следующие за первым, конвейеризуются прекрасно. Таким образом LDM
занимает %% 2 + 1 + 1 = 5%% циклов, если не была приторможена буфером. Аналогично, восемь выгружаемых элементов занимают всего 9 процессорных циклов (если не тормозится). Если LDM
и STM
прерываются, то продолжают они работать с того момента, на котором они были прерваны. Такая операция продолжения отнимает от 1 до 2 лишних циклов на старте.
STR
и STRH
не могут задерживать работу процессора благодаря буферу выгрузки.Инструкции Cortex M3 | Карта памяти |