Об М4 не скажу? расскажу об М3 Вычисление одного элемента FFT для полуволны сигнала.
long long sum_64;
sum_64 = (signal_summ[3] + signal_summ[4]) * SIN_78_75;
sum_64 += (signal_summ[2] + signal_summ[5]) * SIN_56_25;
sum_64 += (signal_summ[1] + signal_summ[6]) * SIN_33_75;
sum_64 += (signal_summ[0] + signal_summ[7]) * SIN_11_25;
Код который сгенерил компилятор.
LDR R0, [R6,#0xC] ; Все данные с АЦП (16 периодов) просуммированы множим на SIN
LDR R1, [R6,#0x10]
LDR.W R3, [PC, #0x0D14] ; =0x7D8A5F3E ; sin 78.75
ADDS R2, R1, R0
LDR R0, [R6,#0x14]
LDR.W R1, [PC, #0x0D10] ; =0x6A6D98A3 ; sin 56.25
ADD R0, R8
SMULL.W R0, R1, R1, R0
SMLAL.W R0, R1, R3, R2
LDR R2, [R6,#0x18]
LDR.W R3, [PC, #0x0D04] ; =0x471CECE6
ADDS R2, R2, R7
SMLAL.W R0, R1, R3, R2
LDR R2, [SP,#0x14]
LDR.W R3, [PC, #0x0CFC] ; =0x18F8B83C
ADD R2, R9
SMLAL.W R0, R1, R3, R2
Сразу видно, что смещение элементов signal_summ компилятор вычислил и вложил их в код
LDR R1, [R6,#0x10]
LDR R0, [R6,#0x14]
Аналогично при фильтрации идет "сплошной текст" на сколько хватает смещения в команде.
только затем инкремент индексного регистра.
//------------------------------------------
Выборка данных
LDR R1, [R6,#0x10] ; шина ОЗУ
LDR.W R3, [PC, #0x0D14] ; шина ПЗУ
ADDS R2, R1, R0 ; обе шины свободны
LDR R0, [R6,#0x14] ; шина ОЗУ
LDR.W R1, [PC, #0x0D10] ; шина ПЗУ
ADD R0, R8 ; обе шины свободны
SMULL.W R0, R1, R1, R0 ; обе шины свободны
SMLAL.W R0, R1, R3, R2 ; обе шины свободны
Явно видно что нет двух подряд идущих команд обращающихся к одной и той же шине.
Таки образом, при коротких цепочках данных расположенных на разных шинах, и спекулятивной выборке
можно получить заявленные 1.625 тактов на MAC 16*16->32.