Оптимизация gcc приводит к сбою приложения - PullRequest
2 голосов
/ 04 октября 2010

У меня действительно странная проблема с использованием GCC для ARM с включенной оптимизацией. Компиляция моего приложения на 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 и перекомпилирую / перекомпоновываю приложение, я получаю правильные результаты вывода. Как вы можете видеть из флагов, я пытался отключить любую оптимизацию, я думал, что это может вызвать проблемы, но все же не повезло.

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

Спасибо

Ответы [ 4 ]

8 голосов
/ 04 октября 2010

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

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

Измерьте, оптимизируйте, измерьте.

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

Этоне лучшее место для навигации с завязанными глазами.

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

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

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

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

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

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

2 голосов
/ 04 октября 2010

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

1 голос
/ 04 октября 2010

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

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

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

1 голос
/ 04 октября 2010

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

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

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

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

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

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

...