Тест Drhystone на 32-битном микроконтроллере

В настоящее время я делаю сравнение производительности на двух 32-битных микроконтроллерах. Я использовал тест Dhrystone для запуска на обоих микроконтроллерах. Один микроконтроллер имеет I-кэш 4 КБ, а второй - 8 КБ I-кеша. Оба микроконтроллера используют одну и ту же цепочку инструментов. В максимально возможной степени я сохранил те же статические и временные настройки на обоих микроконтроллерах. Но микроконтроллер с кешем 4KB работает быстрее, чем микроконтроллер кеша 8KB. Оба микроконтроллера принадлежат одному поставщику и основаны на одном и том же процессоре.

Может ли кто-нибудь предоставить некоторую информацию, почему микроконтроллер с 4KB кешем работает быстрее других?

1 ответ

Тесты вообще бесполезны. dhrystone - один из старейших, и он мог иметь небольшую ценность в то время, до конвейеров и слишком большой оптимизации компилятора. Я думаю, что разочаровался в dhrystone 15 лет назад, примерно в то время, когда начал его использовать.

Это тривиально, чтобы продемонстрировать, что этот код

.globl ASMDELAY
ASMDELAY:
    sub r0,r0,#1
    bne ASMDELAY
    bx lr

Это, в основном, две ИНСТРУКЦИИ, может варьироваться в широких пределах времени выполнения на одном и том же чипе, если вы понимаете, как работают современные процессоры. Простой трюк, чтобы увидеть это, - отключить кеши и программы предварительной выборки и т. Д. И поместить этот код в смещение 0x0000, вызвать его с некоторым значением. поместите его в 0x0004, затем повторите в 0x0008. продолжай делать это. Вы можете поместить один, два и т. Д. Между вычитанием и ответвлением. попробуйте это в различных смещениях.

ТО, включите и кэши для каждого из этих выравниваний, если у вас есть предварительная выборка вне процессора для флэш-памяти, включите и выключите это.

ПОТОМ изменяйте свои часы, особенно для тех MCU, где вы должны настроить состояния ожидания на основе тактовой частоты.

На ОДНОМ MCU вы увидите, что эти две инструкции существенно различаются по времени выполнения. Скажем, в одних случаях в 20 раз дольше, чем в других.

Теперь возьмите небольшую программу или небольшую часть программы dhrystone. Скомпилируйте это для своего mcu, сколько инструкций вы видите? Внесите небольшие изменения в основные и другие изменения в командной строке компиляции, насколько сильно изменяется код. Если две инструкции могут отличаться друг от друга, давайте вызовем их 20 раз во время выполнения, насколько плохо они могут получить 200 инструкций или 2000 инструкций? Это может стать довольно плохо.

Если вы возьмете программы dhrystone, которые у вас есть прямо сейчас, с опциями компилятора, которые у вас есть прямо сейчас, зайдите в ваш загрузчик, добавьте один nop (приводящий к смещению всего двоичного файла на одну инструкцию во флэш-памяти) снова. Добавьте два, три, четыре. Вы по-прежнему не сравниваете разные mcus, просто запускаете тест на одной системе.

Запускайте с и без d кеша, с i и без кеша, если у вас есть каждый из них включите и выключите предварительную выборку флэш-памяти, если она у вас есть, и если у вас есть буфер записи, вы можете включить и попробовать это. Все еще остается на том же компиляторе те же параметры, что и Mcu.

Возьмите различные функции в исходном коде dhrystone и перегруппируйте их в исходном коде. вместо Proc_1, Proc_2, Proc_3 сделайте его Proc_1, Proc_3, Proc_2. Сделайте все вышеописанное снова. Переставьте снова, повторите.

Перед выходом из этого mcu вы должны увидеть, что время выполнения одного и того же исходного кода, который полностью не модифицирован (кроме, возможно, переупорядочения функций), может и будет иметь совершенно разные времена выполнения.

затем, если вы начнете изменять параметры компилятора или оставить тот же исходный код и изменить компиляторы, вы увидите еще большую разницу во времени выполнения.

Как это возможно, что тесты Dhrystone сегодня или с давних времен имели один результат для каждой платформы? Просто, этот результат был лишь одним из широкого диапазона, не представляющего платформу.

Так что, если вы попытаетесь сравнить две разные аппаратные платформы, будь то одно и то же ядро ​​в разных mcu от одного или разных поставщиков. ядро руки, если предположить (что не является безопасным предположением), это тот же источник с теми же параметрами компиляции / сборки, даже если предположить, что использовались одинаковые компиляции и синтеза verilog. Вы можете сделать то же самое изменение ядра, основываясь на опциях, предоставленных рукой. В любом случае, как поставщик, будь то один и тот же поставщик в двух экземплярах, так и два разных поставщика обертывают одно и то же ядро, вы увидите изменения. Затем возьмите совершенно другое ядро, будь то другая рука или мипс, и т. Д. Как вы могли бы получить какую-либо ценность, сравнивая тех, кто использует такую ​​программу, которая сама по себе сильно различается на каждой платформе?

Вы не можете. Что вы можете сделать, это использовать тесты, чтобы создать иллюзию того, что одна вещь лучше другой, один компьютер быстрее другого, один компилятор быстрее другого. Для того, чтобы продать компьютеры или компиляторы. Спринт охват составляет один процент от Verizons... это говорит нам что-нибудь полезное? Нету.

Если вы должны исключить компилятор из уравнения, и если это действительно один и тот же "ЦП", тот же оборот источника из ARM, построенный таким же образом, то они должны извлечь то же самое, но размер кэша является частью так что это может быть уже другая реализация процессора, так как ширина или глубина кэша могут влиять на вещи. В программном обеспечении это все равно, что использовать 32-битный указатель, а не 16-битный указатель (17-битный вместо 16-ти, но вы не можете иметь 17-битный, как правило, в логике).

В любом случае, если вы компилируете тестируемый код один раз для адресного пространства, которое является общим для обеих платформ, используйте один и тот же двоичный файл именно для этого пространства, при необходимости можете присоединить другой код начальной загрузки, обратите внимание, что вызовы библиотеки C strcpy и т. Д. Также должны быть одинаковым в одном и том же пространстве между платформами, чтобы компилятор и выравнивание не мешали вам. это может или не может выровнять игровое поле.

Если вы хотите верить, что это один и тот же процессор, то отключите кэши, устраните различия в компиляторе, выполнив вышеуказанное. Посмотрите, выполняют ли они то же самое. Скопируйте программу в оперативную память и запустите в оперативной памяти, устраните проблемы со вспышкой. Я предполагаю, что вы оба работали одинаково с одинаковыми состояниями ожидания во вспышке?

если они представляют собой один и тот же процессор, и поставщик микросхем с этими двумя микросхемами заставил систему памяти использовать одинаковое количество часов, скажем, для доступа к оперативной памяти, и это действительно тот же процессор, вы должны иметь возможность получить то же время, исключая оптимизации (кэширование, предварительная выборка, выравнивание).

то, что вы, вероятно, видите, это какая-то форма выравнивания с тем, как код лежит в памяти из строк компилятора и кеша, или это может быть намного проще, это могут быть только различия в кешах, как работают попадания и пропуски, и 4 КБ просто больше повезло, чем 8KB для этой конкретной программы, скомпилированной определенным образом, выровненной в памяти определенным образом и т. д.

С помощью простого цикла из двух инструкций, приведенного выше, легко увидеть некоторые причины, по которым производительность меняется в одной и той же системе, если ваш современный процессор выбирает 8 инструкций за раз, и ваш цикл слишком близко подходит к концу этой выборки, предварительной выборке. может подумать, что нужно получить еще 8 сверх того, что стоило бы вам этих тактов. Конечно, поскольку вы точно используете две "строки выборки", как я их называю с этими двумя инструкциями, это будет стоить вам гораздо больше циклов за цикл, даже с кешем. Та же самая проблема возникает, когда эти две инструкции приближаются к строке кэша (поскольку вы меняете их выравнивание для теста), в конечном счете для получения этих двух инструкций требуется два чтения строки кэша вместо одной. По крайней мере, в первый раз происходит чтение дополнительной строки кэша. Дополнительные часы для этого первого раза - это то, что вы можете увидеть, используя простой тестовый пример, подобный этому, играя с выравниванием.

Майкл Абраш, дзен ассемблера. Существует epub / etc, который вы можете собрать из github этой книги. 8088 был устаревшим, когда вышла эта книга, если это все, что вы видите в 8088, тогда вы полностью упускаете суть. Это относится к самым современным процессорам на сегодняшний день: как посмотреть на проблему, как протестировать, как рассчитать время теста, как интерпретировать результаты. Все то, что я упомянул до сих пор, и все, что я знаю об этом, но не упомянуло, все пришло из того, что знания книг применялись на протяжении многих десятилетий, которыми я занимался.

Итак, еще раз, если вы действительно исключили компилятор, выравнивание, процессор, систему памяти, привязанную к этому процессору, и т. Д., И это зависит только от размера кэша. Тогда это, вероятно, связано с тем, как по-разному выбираются строки кэша, в зависимости от выравнивания кода относительно строк кэша для двух кэшей. Один ударяет больше и пропускает меньше и / или выселяет лучше для этого конкретного бинарника. Вы можете попробовать переставить функции, добавить nops, или, если вы не можете получить начальную загрузку, затем добавить целые функции или больше кода (другой printf и т. Д.) По более низкому адресу в двоичном файле, заставляя компоновщик скользить тестируемый код до разные адреса меняют то, как программа выстраивается в линию со строками кэша. Поскольку функции в тестируемом коде настолько велики (их нужно реализовать несколькими инструкциями), вам придется начать модификацию программы, чтобы получить более точную настройку двоичного кода относительно строк кэша.

Вы определенно должны увидеть разницу во времени выполнения на двух платформах, если вы отрегулируете выравнивание и / или измените структуру бинарного файла в зависимости от переупорядочения функций.

Итоговые результаты на самом деле не очень много говорят о вас, результаты имеют скорее негативную сторону, чем позитивную радость. Без перезаписи определенный тест или приложение может работать лучше только на одной платформе (будь то все одинаково, но размер кэша или две совершенно разные архитектуры), даже если вы пытаетесь изменить результаты из-за выравнивания, включения и отключение предварительной выборки, буферизации записи, прогнозирования ветвлений и т. д. Извлечение всех трюков, которые вы можете придумать, может варьироваться от x до y, другого - от n до m, и, возможно, некоторые диапазоны перекрываются. Для этих двух платформ, которые, как вы говорите, похожи, за исключением размера кэша, я надеюсь, что вы сможете найти комбинацию, в которой иногда A быстрее, чем B, и хотя бы одну комбинацию, где B быстрее, чем A, с одинаковыми функциями, включенными и выключенными для обоих. в этом сравнении. Если / когда вы переключаетесь на какое-то другое приложение / тест, все начинается снова, нет никаких оснований предполагать, что результаты dhrystone предсказывают любой другой тестируемый код. Единственная программа, которая имеет значение, особенно на MCU, - это окончательная сборка вашего приложения. Просто помните, что изменение одной строки кода или даже добавление одного nop в загрузчик может привести к впечатляющим результатам в производительности, иногда в несколько раз медленнее или быстрее от одного nop.

Другие вопросы по тегам