Я слышал из разных источников (хотя в основном от моего коллеги), что компиляция с уровнем оптимизации -O3
в g ++ как-то «опасна», и ее следует избегать в целом, если в этом нет необходимости.
Это правда, и если да, то почему? Должен ли я просто придерживаться -O2
?
c++
optimization
g++
compiler-flags
Dunnie
источник
источник
-O3
считается особенно глючит? Я думаю, что, возможно, это может сделать неопределенное поведение «хуже», поскольку оно может делать странные и удивительные вещи, основанные на определенных предположениях, но это будет вашей собственной ошибкой. В общем, я бы сказал, что все в порядке.-O2
включается-fstrict-aliasing
, и если ваш код выживет, то он, вероятно, переживет другие оптимизации, поскольку люди ошибаются снова и снова. Тем не менее,-fpredictive-commoning
это только в-O3
, и включение, которое может привести к ошибкам в вашем коде, вызванным неправильными предположениями о параллелизме. Чем менее неправильный ваш код, тем менее опасна оптимизация ;-)-Ofast
, оно отключает, например, IEEE-совместимую обработку NaNОтветы:
В первые дни gcc (2.8 и т. Д.), А также во времена egcs и redhat 2.96-O3 иногда были довольно глючными. Но это более десяти лет назад, и -O3 мало чем отличается от других уровней оптимизации (в том, что касается ошибок).
Тем не менее, он, как правило, выявляет случаи, когда люди полагаются на неопределенное поведение, поскольку они более строго следуют правилам и особенно угловым случаям языка (ов).
Что касается меня, я уже много лет работаю с производственным программным обеспечением в финансовом секторе с -O3 и еще не столкнулся с ошибкой, которой бы не было, если бы я использовал -O2.
По многочисленным просьбам вот дополнение:
-O3 и особенно дополнительные флаги, такие как -funroll-loops (не включены -O3), могут иногда приводить к генерированию большего количества машинного кода. При определенных обстоятельствах (например, на процессоре с исключительно небольшим кешем команд L1) это может вызвать замедление из-за всего кода, например, некоторого внутреннего цикла, который больше не вписывается в L1I. Обычно gcc старается не генерировать так много кода, но так как он обычно оптимизирует общий случай, это может произойти. Опции, особенно склонные к этому (например, развертывание цикла), обычно не включаются в -O3 и соответственно отмечаются на странице руководства. Поэтому обычно рекомендуется использовать -O3 для генерации быстрого кода и использовать только -O2 или -Os (который пытается оптимизировать размер кода), когда это уместно (например, когда профилировщик указывает, что L1I отсутствует).
Если вы хотите довести оптимизацию до крайности, вы можете настроить gcc с помощью --param затрат, связанных с определенной оптимизацией. Кроме того, обратите внимание, что теперь у gcc есть возможность помещать атрибуты в функции, которые управляют настройками оптимизации только для этих функций, поэтому, когда вы обнаружите, что у вас есть проблема с -O3 в одной функции (или хотите попробовать специальные флаги только для этой функции), Вам не нужно компилировать весь файл или даже весь проект с O2.
Ото кажется, что следует соблюдать осторожность при использовании -Ofast, который гласит:
что заставляет меня заключить, что -O3 предназначен для полного соответствия стандартам.
источник
std::sort
функций вряд ли поможет. Было бы полезно использовать что-то вроде stackoverflow.com/questions/109710/… или, возможно, написать исходный код, чтобы воспользоваться преимуществами сортировки: сканирование до тех пор, пока вы не увидите> = 128, затем начните суммирование. Что касается раздутого кода, то я собираюсь сообщить об этом. : PПо моему довольно скучному опыту, применение
-O3
ко всей программе почти всегда делает ее медленнее (по сравнению с-O2
), потому что включает агрессивное развертывание цикла и встраивание, что делает программу больше не вписывающейся в кэш команд. Для более крупных программ это также может быть верно для-O2
относительно-Os
!Предполагаемый шаблон использования для
-O3
: после профилирования вашей программы вы вручную применяете ее к небольшому числу файлов, содержащих критические внутренние циклы, которые на самом деле выигрывают от этих агрессивных компромиссов между скоростью и пространством. Более новые версии GCC имеют режим оптимизации по профилю, который может (IIUC) выборочно применять-O3
оптимизации к горячим функциям - эффективно автоматизируя этот процесс.источник
Опция -O3 включает более дорогие оптимизации, такие как встраивание функций, в дополнение ко всем оптимизациям нижних уровней '-O2' и '-O1'. Уровень оптимизации '-O3' может увеличить скорость результирующего исполняемого файла, но также может увеличить его размер. При некоторых обстоятельствах, когда эти оптимизации не являются благоприятными, эта опция может на самом деле замедлить работу программы.
источник
Да, O3 хуже. Я разработчик компилятора, и я обнаружил явные и очевидные ошибки gcc, вызванные тем, что O3 генерировал ошибочные инструкции по сборке SIMD при сборке собственного программного обеспечения. Из того, что я видел, большинство производственного программного обеспечения поставляется с O2, что означает, что O3 будет уделяться меньше внимания при тестировании и исправлении ошибок.
Подумайте об этом так: O3 добавляет больше преобразований поверх O2, что добавляет больше преобразований поверх O1. По статистике, больше трансформаций означает больше ошибок. Это верно для любого компилятора.
источник
Недавно у меня возникла проблема с использованием оптимизации с
g++
. Проблема была связана с картой PCI, где регистры (для команд и данных) были переэкрантированы по адресу памяти. Мой драйвер сопоставил физический адрес с указателем в приложении и передал его вызываемому процессу, который работал с ним так:Карта не работает, как ожидалось. Когда я увидел сборку я понял , что компилятор написал только
someCommand[ the last ]
вpciMemory
, минуя все предыдущие записи.В заключение: будьте аккуратны и внимательны с оптимизацией.
источник
pciMemory
какvolatile
.pciMemory
потому что все другие записи доказуемо не имеют никакого эффекта. Для оптимизатора это удивительно, потому что он может удалить много бесполезных и отнимающих много времени инструкций.