Итак, давайте просто попробуем. НУКЛЕО-F767ZI
Cortex-M7 в целом:
Prefetch Unit
The Prefetch Unit (PFU) provides:
1.2.3
• 64-bit instruction fetch bandwidth.
• 4x64-bit pre-fetch queue to decouple instruction pre-fetch from DPU pipeline operation.
• A Branch Target Address Cache (BTAC) for the single-cycle turn-around of branch predictor state and target address.
• A static branch predictor when no BTAC is specified.
• Forwarding of flags for early resolution of direct branches in the decoder and first execution stages of the processor pipeline.
Для этого теста предсказание ветвлений мешает, поэтому отключите его:
Установите ACTLR на 00003000 (шестнадцатеричный, большинство чисел здесь шестнадцатеричные)
Не вижу, как отключить PFU, в любом случае не ожидал бы иметь такой контроль.
Таким образом, мы ожидаем, что предварительная выборка будет считывать 64 бита за раз, 4 инструкции на выровненной границе.
От ST
Бит DBANK установлен, указывая на один банк.
Предварительная выборка инструкций
В случае режима одного банка (установлен опциональный бит nDBANK) 256 бит, представляющих от 8 инструкций по 32 бита до 16 инструкций по 16 бит в соответствии с запущенной программой. Так, в случае последовательного кода для выполнения предыдущей считанной строки инструкции требуется не менее 8 циклов ЦП.
Так что ST собирается превратить это в 256-битную или 16-ю инструкциями.
Использование системного таймера. Я работаю на частоте 16 МГц, поэтому флэш-память находится в нулевом состоянии ожидания.
08000140 <inner>:
8000140: 46c0 nop ; (mov r8, r8)
8000142: 46c0 nop ; (mov r8, r8)
8000144: 46c0 nop ; (mov r8, r8)
8000146: 46c0 nop ; (mov r8, r8)
8000148: 46c0 nop ; (mov r8, r8)
800014a: 46c0 nop ; (mov r8, r8)
800014c: 3901 subs r1, #1
800014e: d1f7 bne.n 8000140 <inner>
00120002
Итак, 12 тактов на цикл. Две предварительные выборки от ARM, первая становится одиночной выборкой ST. Должно быть нулевое состояние ожидания. Обратите внимание на адрес, это AXIM
Если я уменьшу количество nops, оно останется на 0x1200xx, пока здесь:
08000140 <inner>:
8000140: 46c0 nop ; (mov r8, r8)
8000142: 46c0 nop ; (mov r8, r8)
8000144: 3901 subs r1, #1
8000146: d1fb bne.n 8000140 <inner>
00060003
Подтягивание одной рукой вместо двух. Время сократилось вдвое, поэтому предварительная выборка доминирует в нашей производительности.
08000140 <inner>:
8000140: 46c0 nop ; (mov r8, r8)
8000142: 46c0 nop ; (mov r8, r8)
8000144: 46c0 nop ; (mov r8, r8)
8000146: 46c0 nop ; (mov r8, r8)
8000148: 3901 subs r1, #1
800014a: d1f9 bne.n 8000140 <inner>
000 (zero wait states)
00120002
001 (1 wait state)
00140002
002 (2 wait states)
00160002
202 (2 wait states enable ART)
0015FFF3
Почему это повлияет на AXIM?
поэтому каждое состояние ожидания добавляет 2 такта на цикл, есть две выборки на цикл, так что, возможно, каждая выборка заставляет st выполнять одну из своих 256-битных выборок, которая кажется сломанной.
Переключиться на ITCM
00200140 <inner>:
200140: 46c0 nop ; (mov r8, r8)
200142: 46c0 nop ; (mov r8, r8)
200144: 46c0 nop ; (mov r8, r8)
200146: 46c0 nop ; (mov r8, r8)
200148: 3901 subs r1, #1
20014a: d1f9 bne.n 200140 <inner>
000
00070004
001
00080003
002
00090003
202
00070004
ram
00070003
Таким образом, только ITCM, нулевое состояние ожидания, выключенное ART составляет 7 тактов на цикл для цикла из 6 инструкций с ответвлением. кажется разумным. Для этого крошечного теста включение ART с 2 состояниями ожидания возвращает нас к 7 на цикл.
Обратите внимание, что из оперативной памяти этот код также работает со скоростью 7 за цикл. попробуем другую пару
00F
00230007
20F
00070004
Я не искал других предсказателей ветвления, кроме BTAC.
Первое, что нужно отметить, вы не хотите когда-либо запускать MCU быстрее, чем вам нужно, сжигает энергию, многим вам нужно добавить состояния ожидания флэш-памяти, многие процессоры и периферийные устройства имеют разные максимальные тактовые частоты, поэтому есть граница, где это становится нелинейный (занимает X тактов с низкой тактовой частотой, периферийные часы = такт ЦП, есть место, где в N раз быстрее NX тактов, чтобы что-то сделать, но есть одна или несколько границ, где требуется больше, чем N X, чтобы сделать что-то, когда тактовая частота процессора в N раз быстрее). Эта конкретная часть имеет эту нелинейную проблему. Если вы используете библиотеки от ST для установки часов, то, возможно, вы получаете состояние ожидания флэш-памяти в худшем случае, где, если вы настроите его и прочитаете документацию, вы сможете сбрить один или два/несколько.
У Cortex-M7 есть дополнительные кэши L1, на этот раз я не возился с ними, но у ST была эта штука ART до того, как они вышли, и я полагаю, что они, по крайней мере, отключают / отключают кэш i, будет ли это лучше или хуже иметь оба? Если он есть, то это сделает первое прошедшее медленным, а остальные, возможно, быстрее, даже в пространстве AXIM. Вы можете попробовать это. Кажется, помнится, что они сделали что-то хитрое с ремешком на ядре процессора, было непросто увидеть, как он был побежден, и это может быть не этот чип/ядро, но определенно ST. У M4 нет кеша, так что это должен быть M7, с которым я возился (в частности, с этим).
Таким образом, краткий ответ: производительность не так уж ужасна, если вы не используете ART и/или не используете AXIM. ST реализовал флэш-память таким образом, что интерфейс ITCM работает быстрее, чем AXIM. Мы можем увидеть эффекты выборки ARM, если вы включите прогнозирование ветвлений, вы также можете увидеть это, если включите его.
Нетрудно создать бенчмарк, который не учитывал бы эти функции, точно так же, как вы можете создать тест, в котором кэши L1 (или любой другой кэш) снижают производительность. ART, как и любой другой кеш, делает производительность менее предсказуемой, и когда вы изменяете свой код, добавляете строку или удаляете строку, производительность может в результате резко подскочить от нуля до большого количества изменений.
В зависимости от процессора, размера выборки и выравнивания производительность вашего кода может варьироваться за счет добавления или удаления кода над частями проекта, чувствительными к производительности, но это зависит от некоторых факторов, которые мы редко видим.
Трудно сказать, похоже, они утверждают, что АРТ снижает мощность. Я ожидаю, что это увеличит мощность при включении / тактировании этих sram. Не вижу очевидного, сколько вы сэкономите, если выключите вспышку и побежите из оперативной памяти. Детали M7 на самом деле не предназначены для маломощных деталей, таких как некоторые детали STM32L, где вы можете получить единицы / десятки микроампер (микро, а не милли, это было сделано).
Небольшое количество тактов 0x70004 вместо 0x70000 связано с некоторыми накладными расходами на выборку, будь то ARM, ST или их комбинация. Чтобы увидеть производительность памяти/флэш-памяти, вам нужно отключить как можно больше функций, таких как прогнозирование ветвлений, кеши, которые вы можете отключить, и т. д. В противном случае сложно измерить производительность, а затем сделать предположения о том, что делает флэш-память/память/шина. Я подозреваю, что есть еще вещи, которые я не отключил, чтобы сделать чистое измерение, и/или не могу отключить. И простые циклы nop (пробовали другие не-nop-инструкции, не меняли) не расскажут вам всего. Используя документы в качестве руководства, вы можете попытаться кэшировать ART или что-то другое и посмотреть, какие хиты для этого нужны.
Код, критически важный для производительности, вы можете запустить из ОЗУ и избежать всех этих проблем, я не искал его, но предполагаю, что эти части SRAM могут работать так же быстро, как и ЦП. Ответ не прыгает на меня, вы можете понять это.
Обратите внимание, что мой тест на самом деле выглядит так
ldr r2,[r0]
inner:
nop
nop
nop
nop
sub r1,#1
bne inner
ldr r3,[r0]
sub r0,r2,r3
bx lr
где выборка systick находится прямо перед и позади. Перед веткой. Чтобы измерить ART, вы хотели бы выбрать время до перехода для диапазона памяти, который не был прочитан, волшебным образом невозможно прочитать, что быстрее первое чтение в кеш должно быть медленнее. Если я перенесу временную выборку дальше, я увижу, что она меняется с 0x7000A на 0x70027 для состояний ожидания от 0 до 15 с включенным ART. Это заметное снижение производительности для переходов в код, который еще не был запущен/кэширован. Зная размер художественных выборок, должно быть легко сделать тест, который много прыгает, и функция ART начинает не иметь значения.
Короткий ответ: ITCM — это другой интерфейс шины на ядре ARM, ST реализовал свою конструкцию таким образом, чтобы получить прирост производительности. Таким образом, даже без включенного ART использование ITCM быстрее, чем AXIM (вероятно, дело в шине ARM, а не во флэш-памяти ST). Если вы работаете с достаточно высокой тактовой частотой, чтобы добавлять состояния ожидания во флэш-память, то ART может в основном стереть их.
person
old_timer
schedule
03.02.2020