Дроздов А.Ю. (alexander.y.drozdov@gmail.com) - Московский физико-технический институт (технический университет) (профессор), Долгопрудный, Россия, доктор технических наук, Фонин Ю.Н. (fonin.iun@mipt.ru) - Московский физико-технический институт (технический университет) (научный сотрудник), Долгопрудный, Россия, Перов М.Н. (coder@frtk.ru) - Московский физико-технический институт (технический университет) (лаборант), Долгопрудный, Россия, Герасимов А.С. (samik.mechanic@gmail.com ) - Московский физико-технический институт (технический университет) (лаборант), Долгопрудный, Россия | |
Ключевые слова: языки описания архитектур, qemu, симулятор |
|
Keywords: architecture describing languages, qemu, simulator |
|
|
Проектирование современных микропроцессорных систем на кристалле невозможно без создания и использования программных симуляторов. Симулятор используется как для верификации аппаратной платформы, так и для разработки, отладки и оптимизации приложений до момента получения микросхемы с фабрики [1]. В ряде случаев симулятор позволяет получить детальную информацию о работе программы, которую невозможно получить при запуске программы на микропроцессоре, например, информацию о длительности и причине блокировок конвейера для каждой исполняемой инструкции. При отладке больших приложений принципиальным становится вопрос скорости работы симулятора. Одним из способов создания быстрого симулятора является применение бинарной трансляции – преобразований последовательности инструкций эмулируемой архитектуры в инструкции архитектуры процессора, на котором осуществляется эмуляция. Такой подход позволяет достичь скорости работы симулятора до нескольких сотен мегагерц. Существует ряд симуляторов с открытым кодом, среди которых самый известный – QEMU (quick emulator) [2–4], также известны реализации симуляторов на основе компилятора LLVM (low level virtual machine) [5]. Ключевым недостатком симуляторов на основе бинарной трансляции является сложность разработки и отладки симулятора, поскольку код инструкций представляется не в виде С/С++ текста, а как последовательность микроинструкций, которые затем будут транслироваться в код целевой машины. При этом отладка оттранслированного кода стандартны- ми отладочными инструментами, такими как, например, GNU Debugger [6], сокращенно GDB, невыполнима, так как исполняемый бинарный код невозможно связать с исходным кодом программы. Для отладки таких симуляторов по сути доступна только возможность трассировки через вывод лога на консоль или в файл. Однако даже вывод лога не всегда позволяет получить всю необходимую информацию для быстрой локализации ошибок. Ускорить разработку симуляторов на основе бинарной трансляции можно посредством высокоуровневых языков описания архитектур [7]. Эти языки содержат в себе описание, двоичное представление, ассемблерную мнемонику и семантику инструкции, что позволяет реализовать автоматическую генерацию алгоритмов бинарной трансляции, а также сгенерировать структуры и функции для поддержки подсистем отладки. Одним из таких высокоуровневых языков является PPDL (processor and periphery description language) [8]. В статье описываются метод внедрения новой архитектуры в QEMU и подход к отладке созданного эмулятора, основанные на использовании языка описания архитектур высокого уровня PPDL. Особенности архитектуры симулятора QEMU Ключевое отличие симулятора на основе QEMU от обычного C++/SystemC-симулятора в том, что операции в QEMU должны представляться в виде микроопераций фронтенда Tiny Code Generator, сокращенно TCG [2]. Далее эти микрооперации будем называть TCG-операциями. Представление большей части кода в виде TCG-операций – основная задача для интеграции архитектуры в симулятор, поскольку такое начальное преобразование кода обеспечивает значительный прирост производительности при эмуляции и работе процессора на QEMU. Это объясняется тем, что генератору TCG требуется меньше машинного времени и прочих технических затрат на преобразование кода в промежуточное представление. Процесс преобразования кода наглядно представлен на схемах (рис. 1–3). На входе TCG-модуля имеется некий гостевой код, команды которого относятся к поддерживаемой в QEMU архитектуре. Функция gen_intermediate_code() осуществляет преобразование гостевого кода в промежуточное представление QEMU, которое состоит из TCG-операций. Из промежуточного кода функция tcg_gen_code() осуществляет перевод TCG-операций в код целевой платформы, на которой запущен симулятор. Описание всех доступных TCG-операций приведено в файле /tcg/README исходных кодов QEMU, а определение функций, реализующих эти операции, содержится в файле /tcg/tcg-op.h. Простейший вид TCG-функции: tcg_gen_ Зная имена операций, не составляет труда определить нужную функцию генератора, осуществляющую соответствующее действие. В некоторых случаях высокоуровневой операции нет однозначного соответствия в виде одной TCG-операции, тогда приходится составить соответствие в виде цепочки TCG-операций. Возникают и более сложные ситуации, когда самостоятельное преобразование Си-представления какой-либо процессорной функции в промежуточное TCG-представление неэффективно. Для таких случаев существует возможность возложить работу по преобразованию функции на генератор TCG. Этот механизм называется хелпер-функциями. Хелпер-функции (helper functions) – это Си-функции, которые могут быть вызваны напрямую из кода, представленного в виде TCG-операций. Механизм состоит в использовании специальных препроцессорных команд как указание на то, что TCG должен сам преобразовать данную функцию на языке Си в TCG-код. Компиляция хелпер-функций осуществляется на этапе компиляции, собственно, QEMU, а на этапе бинарной трансляции генерируется лишь код вызова данной функции. Задача по встраиванию в QEMU-симулятор новой архитектуры состоит в реализации алгоритма декодирования инструкций и написания кода представления инструкции в виде последовательности TCG-операций. При этом инструментов, позволяющих выполнить, например, пошаговую трассировку исполнения кода, генерируемого из TCG-операций в режиме отладки, не существует. Есть возможность выводить трассы с помощью вставки функций-хелперов, однако этот метод достаточно трудоемкий и допускает возможность внесения ошибок в TCG-код симулятора. Поэтому процесс раз- работки симулятора на основе QEMU является более сложной и трудоемкой задачей, чем про- цесс разработки симулятора на языках С или С++, реализуемого в виде интерпретатора инструкций. Разработка QEMU-симулятора с помощью PPDL Процесс разработки QEMU-симулятора можно существенно упростить, если использовать языки описания архитектур высокого уровня. Одним из них является PPDL – язык для описания ядер микропроцессоров высокого уровня. В PPDL инструкции описываются в явном виде, причем описание инструкции включает в себя, помимо описания семантики, описания ассемблерной мнемоники и бинарного представления инструкции, включая описание полей аргументов инструкции. Благодаря такому представлению компилятор языка PPDL автоматически генерирует из описания архитектуры два симулятора, первый в виде С++ класса, а второй в виде набора компонент для QEMU-симулятора новой архитектуры, а также ассемблер, дизассемблер и набор структур и функций для отладчика. В PPDL для каждой инструкции описываются двоичное представление инструкции, ассемблерная мнемоника инструкции и семантика. В части описания семантики инструкций PPDL можно считать C-подобным языком. Кроме того, в PPDL есть возможность описывать индексируемые множества ресурсов или операций. Например, можно определить множество регистров или множество выражений для вычисления адреса при обращении к памяти. Для каждого множества, как и для инструкции, могут быть заданы ассемблерная мнемоника, двоичный код каждого элемента, а также семантика (в случае, если элемент множества – выражение) или имя ресурса (например, регистра или флага). Использование множеств в качестве типов аргументов инструкций позволяет существенно упростить описание архитектуры за счет переиспользования одних и тех же групп аргументов в различных инструкциях. Наличие в PPDL описания, ассемблерной мнемоники, а также двоичного представления и семантики полезно не только для генерации системного ПО, но и для формирования трасс исполнения инструкций в симуляторах. Для обоих автоматически генерируемых PPDL-компилятором симуляторов (С++ и QEMU) существует универсальный механизм генерации трасс выполнения инструкций. Трасса инструкций позволяет после каждой ис- полненной инструкции вывести следующую информацию: - адрес инструкции; - бинарный код инструкции; - дизассемблер инструкции; - новые значения регистров, если после выполнения инструкций были изменены значе- ния регистров процессора. В случае, если симуляторы C++ и QEMU полностью эквивалентны, трассы одной и той же программы, исполненной на обоих симуляторах, будут одинаковыми. В случае расхождения работы симуляторов можно достаточно легко определить конкретную инструкцию посредством сравнения двух трасс. Возможность автоматической генерации двух симуляторов позволяет выполнить отладку PPDL-описания архитектуры с помощью симулятора С++, который, в отличие от QEMU-симулятора, позволяет использовать стандартные инструменты отладки, например GDB, или отладчик Visual Studio. После отладки с помощью симулятора С++ PPDL-описания архитектуры генерируется код симулятора QEMU, а затем осуществляется его тестирование. Если поведение QEMU-симулятора отличается от поведения симулятора C++, то для локализации ошибки сравниваются их трассы. Сравнение трасс позволяет однозначно определить первую инструкцию, на которой различается поведение, и начать детальное изучение поведения именно этой инструкции. Поведение инструкции в QEMU можно исследовать с помощью вставки отладочных функций-хелперов. Разработка QEMU-симулятора процессора NM6407 Данный подход был применен при разработке симулятора микропроцессора NM6407 семейства NeuroMatrix компании НТЦ «Модуль». Процессор специального назначения NM6407 [9, 10] предназначен для высокоскоростной обработки сигналов и содержит инструкции векторных операций как с фиксированной, так и с плавающей точкой. Принципиальной с точки зрения разработки симулятора особенностью NM6407 является наличие аппаратных очередей FIFO (First in, First out) для выполнения быстрых операций матрично-векторных умножений. Такие очереди не представлены в списке базовых элементов процессоров в QEMU, и для работы с ними нет предусмотренных TCG-операций. Очередь решено было представить в виде структуры следующего вида: typedef struct FIFO_64_9 { int32_t mReadCnt; int32_t mWriteCnt; int32_t setReadCnt; int32_t setWriteCnt; uint64_t fifo[9]; } FIFO_64_9; где 64 – размер элементов FIFO; 9 – размер очереди; mReadCnt и mWriteCnt – маркеры для чтения/записи в очередь. В языке PPDL присутствует такая абстракция, как FIFO-блок, что существенно упростило процесс описания архитектуры NM6407 на PPDL. В симуляторе-интерпретаторе FIFO-блок реализован с помощью класса-шаблона, в котором перегружены операторы присваивания и возвращения значения (оператор «()» в С++). Это существенно упростило генерацию кода симулятора-интерпретатора, так как работа с FIFO с точки зрения кода С++ практически не отличалась от работы с регистрами или флагами. Симулятор QEMU не поддерживает работу с классами С++. Поскольку представление данных процессора в QEMU ограничено использованием переменных типа TCGv (простая структура, содержащая лишь число типа int) и переменных типа TCGv_ptr (переменная, содержащая указатель на некоторую область памяти эмулятора), решением о представлении очередей FIFO будет использование последней в связи со сложностью структуры очереди. При этом возникает дополнительная сложность – генерация функций для работы с FIFO, так как использование указателей вызывает необходимость выполнения многочисленных операций работы с указателями. В силу этого данную работу было решено переложить на генератор TCG – использовать хелпер-функции. Одним из нюансов также является отсутствие полиморфизма в языке Си, поэтому для очередей различных размеров невозможна реализация перегрузок функций. Для разрешения конфликта были использованы препроцессорные вставки и склейки, доступные для хелпер-функций. Заключение Опыт разработки и последующего использования симулятора NM6407 на основе QEMU с помощью языка PPDL показал как интерес к симуляторам на основе бинарной трансляции со стороны разработчиков аппаратных плат- форм, так и реализуемость подхода к разра- ботке QEMU-симуляторов с использованием высокоуровневых языков описания архитек- тур. Использование PPDL также существенно упростило дальнейшую поддержку симулятора, в частности, модификации симулятора, обусловленные необходимостью повторить недокументированные нюансы работы реаль- ной микросхемы, выпущенной в «кремнии». Дальнейшая работа будет направлена на исследование подходов к разработке и отладке многоядерных гетерогенных архитектур на ос- нове симулятора QEMU. Базовая версия QEMU в настоящее время не поддерживает возмож- ность создания симуляторов гетерогенных архитектур, однако имеется открытое решение QEMU-TLM [11], которое является интеграцией QEMU, SystemC и технологии TLM (Transaction Level Modelling) и позволяет создавать симуляторы многопроцессорных систем. Кроме того, применение SystemC дает возможность моделировать не только ядра процессоров, но и модели периферийных устройств, сложных подсистем памяти, включая кэш-память [12], и аппаратных ускорителей. Литература 1. Речистов Г.С., Юлюгин Е.А., Иванов А.А., Шишпор П.Л., Щелкунов Н.Н., Гаврилов Д.А. Программное моделирование вычислительных систем. 2016. 401 с. URL: http://atakua.doesntexist.org/ wordpress/simulation-course-russian/ (дата обращения: 03.07.2019). 2. QEMU Emulator User Documentation URL: https://qemu.weilnetz.de/doc/qemu-doc.html (дата обращения: 03.07.2019). 3. Bellard F. QEMU, a fast and portable dynamic translator. Proc. Conf. USENIX, ATEC, Anaheim, USA, 2005, pp. 41–46. 4. Shen S.T., Lee S.Y., Chen C.H. Full system simulation with QEMU: an approach to multi-view 3D GPU design. Proc. ISCAS, IEEE, Paris, France, 2010, pp. 3877–3880. DOI: 10.1109/ISCAS.2010.5537690. 5. Cook S. AAPSim: Implementing a LLVM Based Simulator. Embecosm, 2016. URL: http://llvm.org/ devmtg/2016-01/slides/fosdem16-aapsim.pdf (дата обращения: 03.07.2019). 6. GNU Debugger description. URL: https://www.gnu.org/software/gdb/ (дата обращения: 03.07.2019). 7. Рубанов В.В. Обзор методов описания встраиваемой аппаратуры и построения инструментария кросс-разработки // Тр. ИСП РАН. 2008. Т. 15. С. 7–40. 8. Фонин Ю.Н. Применение языка PPDL для автоматической генерации средств разработки процессоров // Информационные технологии. 2017. №. 8. Т. 23. С. 583–588. 9. Бирюков А.А., Таранин М.В., Таранин С.В. Процессор 1879ВМ6Я. Реализация глубоких сверточных нейронных сетей // DSPA: Вопросы применения цифровой обработки сигналов. 2017. № 4. Т. 8. С. 191–195. 10. Мушкаев С.В., Бродяженко А.В., Болотников А.А. Вычислительные ресурсы процессоров NeuroMatrix с плавающей точкой в задачах обработки больших потоков данных // Наноиндустрия. 2018. № 9. С. 110–118. DOI: 10.22184/1993-8578.2018.82.110.118. 11. Yeh T.C., Lin Z.Y., Chiang M.C. Enabling TLM-2.0 interface on QEMU and SystemC-based virtual platform. Proc. ICICDT, Kaohsiung, Taiwan, 2011. DOI: 10.1109/ICICDT.2011.5783207. 12. Cheung E., Hsieh H., Balarin F. Memory Subsystem Simulation in Software TLM/T Models. Proc. 14th ASP-DAC, Yokohama, Japan, 2009, pp. 811–816. References
|
http://swsys.ru/index.php?id=4646&lang=.&page=article |
|