Подтвердить что ты не робот

Тестирование оптимизации кода-генератора

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

Вещи, которые я рассмотрел до сих пор:

  • Скомпилируйте контрольные показатели, написанные на C, и изучите полученную ASM, сгенерированную с помощью опции -S. Я сделал это и сравнил результаты с моей оптимизацией с исходными результатами. Этот метод позволяет мне видеть, что моя оптимизация работает, но даже если я пишу пользовательские невыполняемые файлы C, я не смогу проверить все мои требуемые тестовые примеры заказа инструкций.

  • Скомпилируйте тесты для сборки LLVM, отредактируйте это, затем опустите ASM до сборки целевого компьютера. Это может сработать, но из-за различного уровня абстракции между LLVM и целевой ASM я сомневаюсь, что я смогу изучить все тестовые примеры, взломав ASM LLVM, пока он не генерирует то, что я хочу.

  • Используйте целевые тестовые примеры ASM в качестве входных данных для LLVM и перекомпилируйте их с помощью новой оптимизации. Мне не удалось найти вариант для LLVM или gcc (большинство из которых могут принимать LLVM), чтобы принять ASM в качестве ввода.

Какая хорошая стратегия для тестирования конкретных тестов ASM при проверке оптимизации компилятора низкого уровня ASM? Имеет ли LLVM (или gcc) некоторые параметры командной строки, которые облегчили бы этот процесс?


Изменить: Чтобы уточнить, я не спрашиваю о том, чтобы автоматически генерировать тестовые примеры ASM; моя проблема в том, что у меня есть эти тестовые примеры (например, ASM_before.s и reference_ASM_after.s), но мне нужно пройти ASM_before.s в LLVM и убедиться, что оптимизированный вывод ASM_after.s соответствует хорошо известному reference_ASM_after.s. Я ищу способ сделать это без необходимости "декомпилировать" ASM_before.s на высокоуровневый язык и затем скомпилировать его (с оптимизацией) до ASM_after.s.

4b9b3361

Ответ 1

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

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

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

Я обычно запускаю dhrystone, но не объявляю победу или неудачу с этим. Возможно, вы захотите сделать точильный камень, если вы используете поплавок или точильный камень с мягким fpu.

Как уже упоминалось выше, самоконтрольные тесты - хорошая идея. Код реального мира тоже. Например, подпрограммы сжатия, возьмите текст (возможно, часть книги из проекта gutenburg), скомпилируйте его, затем распакуйте и сравните вывод с intput, вы можете добавить дополнительную проверку, сжимая ее на платформе управления, например, на вашем хосте и hardcode сжатый размер в тест, если сжатая версия под тестированием не соответствует, но она получает правильный результат, который все еще не выполняется. Я также использовал библиотеку jpeg для преобразования изображений из/в jpeg, если изображение не должно возвращаться в исходное состояние с сжатием с потерями, тогда вы можете просто сделать одну передачу и контрольную сумму или проверить размер или перенести копию ожидаемый результат и сравнение. Aes и дешифрование и дешифрование.

Есть объемы проектов с открытым исходным кодом, которые вы можете использовать с вашим модифицированным компилятором, чтобы сравнить его с компилятором запаса или другими компиляторами. Будучи кодом реального мира, это то, что ваш компилятор будет использоваться в любом случае. Обратите внимание, что, когда вы переходите на аппаратное обеспечение toms или на другие эталонные сайты, существует множество разных эталонных тестов, времени, которое требуется для рендеринга, времени, необходимого для компиляции gcc или linux или выполнения поиска в базе данных, куча приложений реального мира. И различные приложения получают разные оценки, очень редко, что одна платформа/решение подметает батарею тестов.

Когда ваша производительность падает, когда вы вносите изменения, это время, когда вы изучаете ассемблер и пытаетесь выяснить, почему. Вспомните, что сказал Майкл Абраш (и другие), независимо от того, насколько хорошо вы думаете, что ваш ассемблер вам все равно должен его время. Также попробуйте сумасшедшие вещи, которые, как вы уверены, будут медленными, потому что иногда вы обнаруживаете, что они быстрые по причинам, о которых вы никогда не думали.