Рекомендации GCC и варианты для быстрого кода - PullRequest
24 голосов
/ 09 июня 2010

Я распространяю программу на C ++ с make-файлом для версии Unix и мне интересно, какие параметры компилятора мне следует использовать, чтобы получить максимально быстрый код (он относится к категории программ, которые могут использовать все вычислительные мощности).они могут получить и все еще возвращаться для большего), учитывая, что я не знаю заранее, какое оборудование, операционную систему или версию gcc будет иметь пользователь, и я хочу, прежде всего, убедиться, что он, по крайней мере, корректно работает на всех основныхUnix-подобная операционная система.

Пока у меня есть g++ -O3 -Wno-write-strings, есть ли другие варианты, которые я должен добавить?В Windows у компилятора Microsoft есть опции для таких вещей, как быстрое соглашение о вызовах и генерация временного кода связи, которые стоит использовать, есть ли какие-нибудь эквиваленты в gcc?

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

Ответы [ 7 ]

16 голосов
/ 09 июня 2010

Не зная никакой специфики вашей программы, трудно сказать. O3 покрывает большую часть оптимизаций. Остальные варианты поставляются «по цене». Если вы можете допустить случайное округление и ваш код не зависит от стандартов IEEE с плавающей запятой, тогда вы можете попробовать -Ofast. Это игнорирует соответствие стандартам и может дать вам более быстрый код.

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

Другой вариант - включить C99 (-std = c99) и встроить соответствующие функции. Это немного искусно, вам не следует вставлять все строки, но, немного поработав, вы можете сделать свой код более быстрым (хотя и за счет увеличения исполняемого файла).

Если скорость действительно является проблемой, я бы предложил вернуться к компилятору Microsoft или попробовать Intel. Я пришел к выводу, насколько медленным может быть некоторый скомпилированный код gcc, особенно когда он использует math.h.

РЕДАКТИРОВАТЬ: Ой, подождите, вы сказали, C ++? Тогда не обращайте внимания на мой абзац C99, вы можете уже встроить:)

13 голосов
/ 09 июня 2010

Я бы попробовал оптимизацию по профилю:

-fprofile-generate Включите опции, обычно используемые для инструментов, для создания профиля, полезного для последующей перекомпиляции с оптимизацией на основе обратной связи профиля.Вы должны использовать -fprofile-generate как при компиляции, так и при компоновке вашей программы.Включены следующие параметры: -fprofile-arcs, -fprofile-values, -fvpt.

Также следует дать подсказки компилятору об архитектуре, на которой будет работать программа.Например, если он будет работать только на сервере и вы можете скомпилировать его на том же компьютере, что и сервер, вы можете просто использовать -march=native.В противном случае вам нужно определить, какие функции будут у всех ваших пользователей, и передать соответствующий параметр в GCC.

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

7 голосов
/ 09 июня 2010

-oFast


Пожалуйста, попробуйте -oFast вместо -o3

Также вот список флагов, которые вы можете захотетьвыборочное включение.

-float-store

-fexcess-precision = style

-ffast-math

-fno-rounding-математика

-fno-signaling-nans

-fcx-ограниченный диапазон

-fno-math-errno

-funsafe-math-optimizations

-фассоциативная математика

-фреципрокная математика

-финит-только математика

-фно-подписанные нули

-fno-trapping-math

-frounding-math

-fsingle-precision-constant

-fcx-fortran-rules

полныйСписок флагов и их подробное описание доступно здесь

6 голосов
/ 24 февраля 2012

Попробуйте использовать -fomit-frame-pointer, если только вам не нужно отлаживать с помощью gdb (yuck). Это даст компилятору еще один регистр для использования в качестве переменных (в противном случае этот регистр теряется для бесполезных указателей фреймов).

Также вы можете использовать что-то вроде -march=core2 или, в более общем случае, -march=native, чтобы позволить компилятору использовать более новые инструкции и дополнительно настраивать код для указанной архитектуры, но для этого вы должны быть уверены, что ваш код не будет работать на старых процессорах.

5 голосов
/ 21 сентября 2014

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

Для получения дополнительной информации см. https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

3 голосов
/ 09 июня 2010

gcc -O3 не гарантированно будет самым быстрым.-O2 часто является лучшей отправной точкой.После этого оптимизируйте профиль и опробуйте конкретные параметры: http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

Это длительное чтение, но, вероятно, оно того стоит.

Обратите внимание, что "Link Time Generation Code" (MSVC) aka«Оптимизация времени соединения» доступна в gcc 4.5 +

Кстати, для Win64 не существует специального соглашения о вызовах «fastcall».Существует только «the» соглашение о вызовах: http://msdn.microsoft.com/en-us/magazine/cc300794.aspx

1 голос
/ 24 января 2014

В x86-64 нет 'fastcall' - и Win64, и Linux ABI определяют вызовы на основе регистров ("fastcall") как единственное соглашение о вызовах (хотя Linux использует больше регистров).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...