Оптимизация компилятора безопасна? - PullRequest
4 голосов
/ 30 января 2012

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

Кто-нибудь знает способ на самом делеполучить этот тип данных?Можно ли использовать страницу gcc bugzilla для генерации статистики ошибок по сравнению с уровнем оптимизации компилятора?Можно ли вообще получить такие объективные данные?

Ответы [ 6 ]

2 голосов
/ 30 января 2012

Безопасно ли использование компилятора?

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

Что может сделать код безопасным?

Тестирование / использование.

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

Итак, как может I быть безопасным?

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

Тогда для gcc?Я бы использовал -O2 или -Os (как это делает Linux), потому что они, вероятно, получили огромное количество проверок, прямых или косвенных.

Стоит ли включать оптимизацию?

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

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

Это не более разрушительно, чем переключение компиляторов.

1 голос
/ 10 февраля 2012

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

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

while(1) continue;

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

gcc - это монстр, который едва удерживается вместе с клейкой лентой и проволокой. Это похоже на просмотр одного из этих лиц фильмов смерти или что-то в этом роде, если у вас есть эти изображения в голове один раз, вы не можете их разглядеть, они сожжены там на всю жизнь. Так что стоит выяснить для себя, насколько страшен gcc, заглянув за занавес. Но вы не сможете забыть то, что видели. Для различных целей -O0 -O1 -O2 -O3 могут и все с треском провалились с некоторым кодом в определенный момент времени. Точно так же иногда исправление состоит в том, чтобы оптимизировать больше, а не меньше.

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

Самый важный совет - это разработка и тестирование с использованием целевого уровня оптимизации. Если вы разрабатываете и тестируете, всегда собирая для отладчика, у вас есть созданная программа, которая работает в отладчике, вы можете начать все сначала, если хотите, чтобы она работала где-то еще. gcc -O3 работает часто, но люди боятся его, и он не получает достаточного использования для правильной отладки, поэтому он не так надежен. -O2 и без оптимизации -O0 получите много пробега, множество отчетов об ошибках, множество исправлений, выберите один из них или, как сказал другой ответ, используйте то, что использует Linux. Или используйте то, что использует Firefox, или используйте то, что использует Chrome.

Теперь жесткие встроенные системы реального времени. Системы миссий человека, системы, где жизнь или собственность непосредственно затронуты Во-первых, почему вы используете GCC? Во-вторых, да, оптимизаторы часто НЕ используются в этих средах, это создает слишком большой риск и / или значительно увеличивает усилия по тестированию и валидации. Обычно вы хотите использовать компилятор, который сам прошел много испытаний, и его бородавки и ловушки хорошо известны. Вы хотите быть человеком, который включил оптимизатор, и в результате бортовой компьютер в школьный день врезался в начальную школу? У старожилов можно многому научиться. да, у них много военных историй и много страха перед новыми запутанными вещами. Не повторяйте историю, учитесь на ней. «Они строят их не так, как раньше», это означает не просто высказывание. эти устаревшие системы были стабильными и надежными и по-прежнему работали по определенной причине, отчасти те старые таймеры и то, чему они научились на собственном опыте, а отчасти потому, что новые вещи строятся дешевле и с компонентами более низкого качества.

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

Теперь, если эта жесткая среда реального времени не причинит вреда людям или имуществу (кроме того, на чем он работает), когда он рухнет, тогда это уже другая история. Может быть, это проигрыватель Blue Ray, и он пропускает кадр тут или там или отображает несколько плохих пикселей, большое дело. Включите оптимизатор, массы больше не заботятся об этом уровне качества, они довольствуются изображениями с качеством YouTube, сжатыми видеоформатами и т. Д. Автомобили, которые необходимо выключить и снова включить, чтобы радио или Bluetooth работали. Не беспокоить их, включить оптимизатор и заявить о выигрыше в производительности по сравнению с конкурентом Если программное обеспечение слишком глючит, чтобы терпеть, клиенты будут обходить его или просто покупают кого-то другого, если это не удастся, они вернутся к вам и купят вашу новую модель с более новой прошивкой. Они будут продолжать делать это, потому что они хотят танцевать балони, они не хотят стабильности и качества. Этот материал стоит слишком дорого.

Вы должны собрать свои собственные данные, попробовать оптимизаторы программного обеспечения в своей среде и запустить продукт через полный пакет проверки. Если он не ломается, то либо оптимизатор для этого кода в этот день в порядке, либо тестовая система требует дополнительной работы. Если вы не можете этого сделать, вы можете, по крайней мере, разобрать и проанализировать, что компилятор делает с вашим кодом. Я бы предположил (и знаю из личного опыта), что в системах ошибок gcc и llvm есть ошибки, связанные с уровнями оптимизации. Значит ли это, что вы можете сортировать их по уровню оптимизации? Не знаю, это интерфейсы с открытым исходным кодом, в значительной степени неконтролируемые, поэтому вы не можете полагаться на массы для точного и полного определения полей ввода. Если в форме отчета об ошибке было поле оптимизации, для него, вероятно, всегда установлено значение по умолчанию для Форма / веб-страница. Вы должны изучить сам отчет о проблеме, чтобы увидеть, были ли у пользователя проблемы, связанные с оптимизатором. Если бы это была закрытая система для корпорации, в которой оценка эффективности работы сотрудников могла бы быть негативно отражена из-за несоблюдения таких процедур, как правильное заполнение форм, у вас были бы лучше доступные для поиска базы данных для получения информации.

Оптимизатор увеличивает ваш риск. Допустим, 50% компилятора используется для получения вывода без оптимизации, еще 10% для получения -O1, вы увеличили свой риск, больше использовало код компилятора, больше риск ошибки, больший риск в выходе плохой , и больше кода используется, чтобы добраться до -O2 и -O3. Снижение оптимизации не устраняет риск полностью, но уменьшает шансы.

1 голос
/ 30 января 2012

У меня нет никаких данных (и я не слышал ни о ком, кто делает ...), но ...

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

Ядро linux скомпилировано с -Os.Это намного более убедительно для меня, чем любой анализ bugzilla.

Лично я был бы согласен с любой версией gcc linux, с которой все в порядке.

Как другие данныеДело в том, что Apple конвертирует из gcc в llvm, с и без лязга.У llvm традиционно были проблемы с некоторым C ++, и, хотя llvm-gcc теперь намного лучше, кажется, все еще есть проблемы с clang ++.Но это только отчасти доказывает закономерность: хотя Apple (предположительно) теперь компилирует OS X и iOS с Clang, они почти не используют C ++ и Objective C ++.Так что для чистого C и Objective C я бы доверял clang, но я все еще не доверяю clang ++.

0 голосов
/ 23 июня 2017

Во встроенных системах часто необходимо контролировать аппаратное обеспечение путем записи в регистры. В Си это очень просто, просто инициализируйте указатель с адресом регистра, и все - и все.

Если никакая другая часть программы не читает или не записывает регистр, вполне вероятно, что оптимизатор удалит назначение. Взлом кода.

Эта конкретная проблема может быть исправлена ​​с помощью ключевого слова "volatile". Но не забывайте, что оптимизатор также меняет последовательность команд. Поэтому, если ваше оборудование ожидает, что регистры будут записаны в определенном порядке, вас могут сжечь.

Предполагается, что оптимизатор выдаст правильные результаты, но временные шаги могут измениться, именно здесь оптимизатор может нанести вам вред.

0 голосов
/ 01 апреля 2015

Я не знаю об ошибках gcc, но язык программирования C плохо подходит для текущего оборудования. Помните, что это было задумано в 1970-х, когда не было даже ясно, что арифметика дополнения 2 должна была быть будущей. Хорошо, вы добавили 2 целых числа без знака в C. В спецификациях сказано, что вы не можете переполниться. Компилятор может предположить, что флаг переноса сброшен после добавления, и провести дальнейшую оптимизацию на основании этого. Вы предполагаете, что 2 дополняют арифметику (а кто бы не стал в наши дни), и вы просто устанавливаете флаг переноса. Такие вещи являются основным источником проблем безопасности. Я думаю, что Java, вероятно, лучше даже для низкоуровневого кода, потому что он намного лучше определен, и текущий компилятор HotSpot как раз вовремя создает код, который работает так же быстро, как и C. Вы можете взглянуть и на язык программирования D, вероятно, он хорошо определен тоже.

0 голосов
/ 30 января 2012

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

Для получения информации об этой проблеме вы можете проверить:

Может ли оптимизация компилятора вводить ошибки?

...