LINUX.ORG.RU

Можно ли на QEMU делать стабильные бенчмарки мелких ARM?

 ,


0

2

Интересует, насколько точно QEMU эмулирует Cortex M0-M4 (или что там есть из простого), и можно ли там считать время выполнения бенчмарка в тактах процессора.

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

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

★★★★★

Нельзя. Qemu не cycle accurate. И эмулировать циклы даже на системе с Cortex-M4 уже практически невозможно из-за ограничений реальных систем памяти.

alexru ★★★★
()
Ответ на: комментарий от alexru

Окей, фик с ним, с QEMU. Можно мою проблему решить хотя бы для M0? Мне бы хватило. Просто есть есть библиотека LittlevGL для мелких процессоров, и проверять ее бенчмарки на x86 как-то не в тему. Ну и на x86 всплывет та же проблема - у васи и пети разные гигагерцы, операционки. Уже не говоря о том что на Travis-CI загрузка виртуалок вообще как угодно скачет.

Я не совсем в теме, может прошу что-то странное. Но мне показалось, что желание делать стабильные бенчмарки должно было возникать у очень многих, и такую проблему давно должны были решить, пусть даже с ограничениями.

В принципе, устроит даже совсем другое ядро, не ARM, но хотя бы 32-битное.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

Да, это странное желание. Для сравнения ядер используют DMIPS и Coremark. Этого вполне достаточно для быстрой оценки.

Производительность этой библиотеки будет зависеть от периферии, которая рисует пиксели на экран.

И для Cortex-M0 она будет медленная, можно особо не пытаться.

alexru ★★★★
()
Ответ на: комментарий от alexru

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

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

С аппаратной периферией ядро общается через шину, и от архитектуры этой шины и прочей нагрузки зависит производительность.

И в каком CM0 есть железный контроллер LCD? Чего-то не верится.

alexru ★★★★
()
Ответ на: комментарий от alexru

Самое простое - это взять целевые процессоры и сравнивать на реальном железе. Все остальное - это пустая трата времени.

alexru ★★★★
()
Ответ на: комментарий от Vit

Через DWT (Data Watchpoint and Trace) мерять на реальном железе http://infocenter.arm.com/help/topic/com.arm.doc.ddi0432c/BABJHEIG.html

Ну или там в GPIO порт что-то писать в блокирующем режиме, чтоб потом логическим анализатором померить и сделать выводы

Вообще вот нагуглил https://www.arm.com/products/development-tools/simulation/cycle-models https://community.arm.com/developer/tools-software/tools/b/tools-software-ide... какой-то эмулятор

SZT ★★★★★
()
Ответ на: комментарий от SZT

А, ну да, если хочется заморочиться, то ARM дает Verilog исходники Cortex-M0+ и Cortex-M3. Точнее не бывает и как минимум M0+ под iverilog работает отлично.

alexru ★★★★
()
Ответ на: комментарий от alexru

Щина SPI c DMA какая есть, и на алгоритмы повлиять не может. Ее вклад постоянен. Не вижу смысла обсуждать то, что не имеет значения для моих задач.

Как померить на железе я догадываютсь. Тему создал, потому что постоянно раскладывать железо неудобно, особенно когда людей много и все занимаются в свободное от работы время. И автоматизировать контроль регрессий усрёшься. Надо чтобы было просто, как обычные тесты после каждого коммита в трависе.

Vit ★★★★★
() автор топика
Ответ на: комментарий от SZT

Тесты тоже можно гонять на реальном железе, и гуй на реальном железе разрабытывать. Только это нахрен не уперлось. Зачем героически преодолевать трудности, если можно делать легко и просто? Хочу чтобы с бенчмарками тоже просто было.

https://github.com/puzrin/dispenser у меня там есть билд для десктопа, просто с другими драйверами, отличий минимум. Если б я на железе все пилил, потратил бы раз в 10 больше времени.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

Зачем героически преодолевать трудности, если можно делать легко и просто? Хочу чтобы с бенчмарками тоже просто было.

Ну если:

В принципе, устроит даже совсем другое ядро, не ARM, но хотя бы 32-битное.

То как выше подсказали, можно взять RISC-V ядро на верилоге https://github.com/ultraembedded/riscv, взять компилятор GCC который под него собирать умеет, разобраться с тем как там измерять производительность, все это как-нибудь состыковать и сделать continuous integration с замером производительности

SZT ★★★★★
()

Конечно же нельзя делать никакие бенчмарки, эмулятор даст максимум скорости твоего процессора на хосте и будет эмулировать набор команд процессора. Ты можешь указать параметр -smp 8, чтобы указать число используемых ядер, но никак не ограничишь скорость выполнения кода. Максимум что можешь, это пытаться его оптимизировать, чтобы в целом он исполнялся быстрее на всех армах.

fehhner ★★★★★
()
Ответ на: комментарий от SZT

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

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

Как вариант - взять симулятор gem5, он поддеживает Cortex-A. Есть проприетарные cycle-accurate симуляторы у ARM (e.g. https://developer.arm.com/tools-and-software/simulation-models/cycle-models/designstart).

На будущее лучше думать в сторону фермы для бенчмарков, именно такой подход предпочитают в индустрии из-за большей надёжности и скорости выполнения. Основная работа будет заключаться в автоматическом обнаружении сбоев и обеспечении стабильных измерений (современный дистрибутив шумит на 3-4%).

yugr
()
Последнее исправление: yugr (всего исправлений: 1)
Ответ на: комментарий от yugr

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

Возможно, ситуация просто не дозрела до состояния когда cycle-accurate симуляторы были бы доступны. Так тоже бывает.

Vit ★★★★★
() автор топика
Ответ на: комментарий от yugr

Спасибо. Он какой-то легкой научной безуминкой отдает :). Страница сайта на вики, отсутствие версий и билдов… Хотя к травису даже такое реально через докер привернуть.

А как его загнать в режим подсчета циклов между началом и концом бенчмарка? Чтобы не учитывать влияние линуксовой обвязки, и результат не сильно плавал независимо от нагрузки хостовой машины?

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

Да, он такой. Но года 4 назад это был лучший OSS-вариант.

А как его загнать в режим подсчета циклов между началом и концом бенчмарка?

Мои скрипты остались у предыдущего работодателя, но в сети вроде хватает примеров e.g. для ARM: http://lacasa.uah.edu/portal/Upload/tutorials/gem5/RunningPrograms-gem5.txt

Чтобы не учитывать влияние линуксовой обвязки и результат не сильно плавал независимо от нагрузки хостовой машины?

Просто мерять хостовое время конечно нельзя, оно никак не коррелирует с симулируемым временем (и да, безбожно шумит, особенно на внешних VM-ах).

yugr
()
Ответ на: комментарий от yugr

Не совсем понял. По ссылке просто инфа как собрать программу кросс-компилятором и с какими ключами запустить gem5. Ничего про измерения там нет. Статистику в циклах он выдает только итоговую, это как средняя температура по больнице.

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

И второй момент, насчет самого проца. Если правильно понимаю, мне достаточно SE mode где чистое ядро без периферии. А какой там самый чахлый проц? На первый вгляд там даже самые убогие имеют кеш, что в моем случае не желательно.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

Статистику в циклах он выдает только итоговую, это как средняя температура по больнице.

Если можно модифицировать код, то можно просто обернуть бенчмарк в gettimeofday, он считает до микросекунды (симулированной). Но вообще обычно делают …

Можно конечно увеличить количество итераций в сотни раз

… так.

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

По моим воспоминаниям там только Cortex-A-профиль из коробки. Кэши можно отключить: https://stackoverflow.com/a/49634544/2170527

yugr
()

Как уже было сказано «в тактах» посчитать нельзя, и маловероятно что такое когда-либо будет в QEMU (ибо такая аккуратность - достаточно нудная ортогональная задача).

Однако, «в среднем по больнице» это очень неплохо работает. Подробностей не помню, но пару лет назад был свидетелем сравнения производительности таким способом. Было 2-3 варианта решения какой-то подзадачи и нужно было их сравнить, причем с учетом использования разных версий компилятора и разных опций оптимизации… (всего получалось больше 100 вариантов).

Собственно собрали и замерили время выполнения 100500 итераций под QEMU. Потом несколько вариантов сравнили на реальном железе - расхождение было в пределах погрешности измерений.

Тем не менее, это точно не будет работать если есть существенная зависимость от спекулятивного выполнения, предсказания ветвлений и специфики доступа к памяти (например к frame buffer).

Deleted
()
Ответ на: комментарий от yugr

https://en.wikipedia.org/wiki/ARM_Cortex-A - судя по описанию, 32-битные кортексы А отличаются от М только наличием MMU. То есть, при отключении кеша результат бенчмарка должен получиться близкий, плюс-минус лапоть.

Давай тогда еще раз уточним:

  • Правильно ли я понимаю, что в итоговой статистике значение sim-ticks будет достаточно стабильным и не зависеть от машины, на которой запускается gen5? И «тик» - это что-то вроде периода тактовой частоты, а не «инструкция», у которой количество тактов плавает очень сильно.
  • Если я увеличу время бенчмарка ориентировочно до 1-10 секунд для «обычного компа», то накладными расходами на запуск и системные вызовы можно будет пренебречь?

Если все так, то собрать бенчмарк и запарсить выхлоп вообще не проблема. А то что gen5 хреначат без меток и билдов, решается докером через зеркало на гитхабе.

Vit ★★★★★
() автор топика
Последнее исправление: Vit (всего исправлений: 1)
Ответ на: комментарий от Deleted

У вас сравнения делались на ОДНОЙ машине. А мне нужна воспроизводимость результатов на РАЗНЫХ.

Посмотрите комменты, QEMU уже проехали, мне gen5 сватают.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

Могу посоветовать глянуть на make cross-qemu в тестах t1ha. Это (наверное) пример максимума, который можно получить «замерами через QEMU».

Deleted
()
Ответ на: комментарий от Deleted

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

Vit ★★★★★
() автор топика
Последнее исправление: Vit (всего исправлений: 1)
Ответ на: комментарий от Vit

gem5 должен достаточно хорошо эмулировать «железо». В зависимости от эмулируемой модели CPU может быть доступен один из таймеров. Соответственно, этот таймер можно считать до и после выполнения бенчмарка. Но универсальное решение может быть достчточно муторным, как пример.


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

Так вот, при работающих в гостевой системе perf-счетчиках, либо одного из «счетчика тактов» (в специфических регистрах CPU), вы сможете использовать mera.c как готовое работающее решение. Собственно вы в любом случае можете его использовать, но при недоступности честно-эмулируемых аппаратных счетчиках у вас будет результат только от clock_gettime().

Deleted
()
Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от Deleted

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

Для быстрой оценки мне хватит точности 10-20%. Для автоматизированных тестов регрессий нужна точность 1% (иначе левыми алертами завалит).

Собственно в этом и вопрос - таки gem5 выдает честные циклы или нет? И отбрасывает ли в SE mode цену системных вызовов.

Vit ★★★★★
() автор топика
Последнее исправление: Vit (всего исправлений: 1)
Ответ на: комментарий от Vit

Охотно поверю что они приложили усилия чтобы считать более-менее точно, но НЕ поверю что у них это идеально получилось. Тем не менее, для ваших задачи это видимо в самый раз, см http://gem5.org/dist/tutorials/hipeac2012/gem5_hipeac.pdf и https://www.lirmm.fr/~sassate/ADAC/wp-content/uploads/2014/11/Accuracy_evaluation-ReCoSoC-2012.pdf,

Deleted
()
Ответ на: комментарий от Deleted

Спасибо за ссылки. Пишут что cycle accurate и выдаваемые результаты не привязаны не привязаны к реальному времени. Осталось разобраться с чисто «бытовыми» вопросами:

  • На практике, бенчмарки удобнее пускать в SE mode. Меньше возни с написанием кода - консольное приложение осилит и локально протестирует даже полный дебил. Но в этом случае Gen5 дополнительно эмулирует поведение линукса, и надо уменьшить это влияние на результат (сделать ниже порогового)
  • Бинарников нет, сборка занимает 20 минут. Надо разбираться, не дропнет ли травис процесс за такое. Можно конечно в крайнем случае самому бинарники на гатхаб выложить, но это совсем зашквар. На всех CI довольно просто настраиваются кеши, и на каждом коммите пересборки сима не будет. Но в первый-то раз он собраться должен.

Однозначно не зря тему создал, очень много интересного и нового узнал.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

https://github.com/arm-university/arm-gem5-rsk/blob/aa3b51b175a0f3b6e75c9c856092ae0c8f2a7cdc/parsec_patches/xcompile-patch.diff#L188-L211

По первой части вроде понятно. Есть «чекпоинты» (фейковые инструкции) которыми можно пометить нужный кусок кода в исходнике, и снять статистику именно по нему. И сбросить статистику в начале региона, если надо.

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

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

https://en.wikipedia.org/wiki/ARM_Cortex-A - судя по описанию, 32-битные кортексы А отличаются от М только наличием MMU.

Конвейер тоже сильно отличается (out-of-order и пр.).

То есть, при отключении кеша результат бенчмарка должен получиться близкий, плюс-минус лапоть.

Нет, out-of-order сильно меняет дело.

Правильно ли я понимаю, что в итоговой статистике значение sim-ticks будет достаточно стабильным и не зависеть от машины, на которой запускается gen5?

В случае если сис. вызовов нет - точно так. Детали эмуляции вызовов я уже не вспомню, но у меня вроде получалось одно и то же число тиков на повторных запусках.

И «тик» - это что-то вроде периода тактовой частоты

Не вроде, а именно оно и есть.

Если я увеличу время бенчмарка ориентировочно до 1-10 секунд для «обычного компа», то накладными расходами на запуск и системные вызовы можно будет пренебречь?

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

yugr
()
Ответ на: комментарий от Vit

На практике, бенчмарки удобнее пускать в SE mode.

Да, иначе придётся ещё бороться с шумом симулируемого дистрибутива (т.н. OS jitter), а это нетривиальная задача (см. например https://github.com/yugr/uInit).

yugr
()
Ответ на: комментарий от yugr

Нет, out-of-order сильно меняет дело.

Что-то оно безусловно меняет, но будет ли это критично для моего случая?

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

Тогда вопрос - можно ли выпилить out-of-order, и стоит ли с этим заморачиваться или плюнуть и юзать как есть?

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

Это я так неудачно спросил про время старта. Если стартует 1 секунду, то чтобы забить разницу надо растягивать тест на 100. Впрочем, раз есть SE и можно в исходниках явно обозначить регион чекпоинтами, то растягивать бенчмарки смысла нет. Внутри региона сисколов точно не будет.

Vit ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.