Итак, ради интереса сделал тест.
Использую аппаратный регистр CYCCNT для подсчета реального количества тактов, затрачиваемых на исполнение кода.
Предварительно процессор настраивается на 180МГц, количество тактов процессора, затрачиваемое на чтение 128 бит из Flash - 6 циклов (5WS).
Код теста:
Код
AREA MY_PROGRAM, CODE, READONLY
ENTRY
MyProg PROC
EXPORT Main
DWT_CYCCNT EQU 0xE0001004
DWT_CONTROL EQU 0xE0001000
SCB_DEMCR EQU 0xE000EDFC
Main
ldr r0, =SCB_DEMCR
mov r1, #0x01000000
str r1, [r0]
ldr r0, =DWT_CONTROL
ldr r1, [r0]
mov r2, #0x1
orr r1, r2
str r1, [r0]
ldr r0, =DWT_CYCCNT
mov r1, #0x0
b loop
LTORG
loop
str.w r1, [r0]
mul.w r3, r4, r5
; ...
; ТЫСЯЧА ТАКИХ ИНСТРУКЦИЙ
; ...
mul.w r3, r4, r5
ldr.w r2, [r0]
b.w loop
ENDP
END
Инструкции как раз подобраны наихудшие: 1 такт исполнение, 32-разрядные из набора Thumb-2.
1. Отключаю кэш инструкций и данных, отключаю prefetch-buffer выборки.
2. Запускаю код на исполнение под отладчиком без точек останова.
3. Пока код выполняется, ставлю точку останова на строку
Код
b.w loop
и смотрю содержимое регистра R2 (считанное значение в 180МГц тактах): 0x8CB = 2251.
4. Время математики: 1000 однотактных 32-разрядных команд, 1000/4=250 циклов обращения к Flash-памяти по 128 бит. С учетом того, что WS=5, 5*250=1250 тактов накладных расходов на ожидание доступа к данным. Прибавляем такты выполнения команд: 1250 + 1000 = 2250. Что на 1 такт меньше считанного показания с системного регистра. Двигаемся дальше.
5. Включаем prefetch-buffer выборки и повторяем шаги 2-3. Содержимое CYCCNT = 1501.
6. Выключаем prefetch-buffer, включаем кэш. Содержимое CYCCNT = 2250. По-моему логично, поскольку в кэше хранятся адреса команд начала последних использованных подпрограмм и веток кода, а не сам код (в документации вроде про это написано).
7. Включаем prefetch-buffer и кэш. Содержимое CYCCNT = 1501.
Как видно, при включенном буфере предвыборки будет потеря производительности, однако если в коде будут использованы не только 32-разрядные инструкции Thumb-2, а 16-разрядные, скорее всего количество тактов совпадет с количеством инструкций между метками замера. Замерил - CYCCNT = 1001.
Отключаю prefetch - CYCCNT = 1251. Интересно, почему сейчас 1251, ведь 8 однотактных инструкций перекрывают 5WS при доступе к Flash... Это пока под вопросом, я разберусь.
Собственно говоря, этих сведений мне достаточно, чтобы полагать, что большого толку от широкой шины на Tiva-C не будет. Она сделана точно для таких же целей, для каких и ART-ускоритель в STM32 - обеспечить нулевое состояние задержки при выполнении смешанного (32-разрядного и 16-разрядного) кодов Thumb и Thumb-2.
Если сравнивать производительность выполнения 32-битного кода Thumb-2 STM32, работающего на частоте, допустим, 150МГц, над производительностью Tiva-C, работающего на 120МГц при выполнении того же 32-битного кода, то плюс широкой шине - бесспорно предвыборка 8 команд лучше чем предвыборка 4. Однако на реальной практике код представляет из себя смесь 16- и 32-разрядных инструкций, поэтому подобный метод расчета производительности не годится, нужны данные CoreMark или Dhrystone.