Оптимизации GCC приводят к выходу из строя приложение

StackOverflow https://stackoverflow.com/questions/3854636

Вопрос

У меня настоящая странная проблема с использованием GCC для рук с включенными оптимизациями. Компиляция моего приложения C ++ без оптимизаций производит исполняемый файл, который при выполнении выводит ожидаемые результаты. Как только я включаю оптимизацию - то есть -O1 - мое приложение не дает ожидаемых результатов. Я пробовал на пару дней, чтобы обнаружить проблему, но я невежему. Я устранил любые неинициализированные переменные из моего кода, я исправил места, где строгие псевдонимы могут вызвать проблемы, но все же у меня нет правильных результатов.

Я использую GCC 4.2.0 для ARM (процессор представляет собой ARM926EJ-S) и запустить приложение на дистрибутиве Montavista Linux.

Ниже приведены флаги, которые я использую:

-O1 -fno-unroll-loops fno-merge-constants -fno-omit-frame-pointer -fno-toplevel-reorder \
-fno-defer-pop -fno-function-cse -Wuninitialized -Wstrict-aliasing=3 -Wstrict-overflow=3 \
-fsigned-char -march=armv5te -mtune=arm926ej-s -ffast-math

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

У кого -нибудь есть какие -либо указатели на то, как я могу еще больше решить эту проблему?

Спасибо

Это было полезно?

Решение

Вообще говоря, если вы говорите, что «оптимизация разбивает мою программу», это 99,9% программирование это сломано. Включение только оптимизации раскрывать Неисправности в вашем коде.

Вы также должны легко пойти в опции оптимизации. Только в очень конкретных обстоятельствах вам нужно что-то еще, кроме стандартных вариантов -O0, -O2, -O3 и возможно -OS. Если вы чувствуете, что вы делать Нужны более конкретные настройки, чем это, прислушиваясь мантру оптимизации:

Измерить, оптимизировать, измерить.

Никогда Иди от "кишечника" здесь. Докажите, что определенная нестандартная опция оптимизации значительно приносит пользу вашему приложению, и понять, почему (т.е. точно понять, что делает этот вариант, и почему это влияет на ваш код).

Это не хорошее место для перемещения с завязанными глазами.

И, видя, как вы используете самый защитный вариант (-O1), затем отключите полдюжины оптимизаций и потом Добавить -fhast-math, ведет меня, чтобы предположить, что вы в настоящее время делаете только это.

Ну, возможно, одноглазый.

Но нижняя строка: если включение оптимизации разбивает ваш код, скорее всего, ваш код вашего кода.

РЕДАКТИРОВАТЬ: Я только что нашел это в руководстве GCC:

-ffast-math: Эта опция никогда не должна быть включена в любой опцию -O, поскольку она может привести к неправильному выходу для программ, которые зависят от точной реализации правил / спецификаций IEEE или ISO для математических функций.

Это говорит, в основном, что ваш -O1 -ffast-math действительно может сломаться верный код. Однако, даже если убрать -ffast-math Удаляет вашу текущую проблему, вы должны, по крайней мере, иметь идею Зачем. Отказ В противном случае вы можете просто обменять вашу проблему Теперь с проблемой в более неудобный момент потом (Вроде, когда ваш продукт перерывается в расположение вашего клиента). Это правда -ffast-math Это была проблема, или у вас сломал код математики, который открыт по -ffast-math?

Другие советы

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

Не видение вашего кода, трудно получить более специфическое, чем «у вас, вероятно, ошибка».

Есть два сценария, в которых включение оптимизации меняет семантику программы:

  • В компиляторе есть ошибка или
  • В вашем коде есть ошибка.

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

Покажите нам свой код. Или выйдите через него в отладчик, пока не дойдете до точки, где все пойдут не так.

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

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

Кстати, если, как у других спекулировали, это -ffast-math который вызывает вашу неприятность (т. е. компиляция только с -O1 Работает нормально), то скорее всего, у вас там есть математика, вы должны в любом случае переписать. Это немного упрощения, но -ffast-math Разрешает компилятору по существу, повторно переставить вычисления, поскольку вы можете абстрактные математические числа - даже если это на реальном аппаратном обеспечении может привести к незначительному разным результатам, так как числа плавающих точек не являются точными. Полагаясь на такого рода детализацию с плавающей точкой, вероятно, будет непреднамеренным.

Если вы хотите понять ошибку, в любом случае является минимальным тестом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top