Каков уровень оптимизации (g ++), Вы используете при сравнении двух различных алгоритмов, записанных в C++?

SoapUI является другим инструментом тестирования веб-сервиса. Я настоятельно рекомендую это.

11
задан Cœur 23 August 2017 в 02:43
поделиться

5 ответов

Это зависит от того, для чего вы хотите оптимизировать.

Скорость

Я предлагаю использовать -O2 -NDEBUG -ftree-vectorize , и если ваш код разработан специально для работы на x86 или x86_64, добавьте -msse2 . Это даст вам общее представление о том, как он будет работать с GIMPLE.

Размер

Я считаю, что вам следует использовать -Os -fno-rtti -fno-exceptions -fomit-frame-pointer . Это в некоторой степени минимизирует размер исполняемого файла (при условии C ++).


В обоих случаях скорость алгоритма не зависит от компилятора, но компилятор может радикально изменить поведение кода, если он может «доказать», что это возможно.

GCC обнаруживает «общие» код, такой как вручную закодированные min () и max () , и превращает их в одну инструкцию SSE (на x86 / x86_64 и когда -msse установлен) или с помощью cmov, когда i686 доступно (SSE имеет более высокий приоритет). GCC также может свободно переупорядочивать циклы, разворачивать и встраивать функции, если захочет, и даже удалять бесполезный код.

Что касается вашего последнего редактирования:

Вы можете видеть, что в -O0 std :: vector - превзошел в два раза быстрее указатели. В то время как в -O2 они почти то же самое.

Это потому, что std :: vector все еще имеет код, который генерирует исключения и может использовать rtti. Попробуйте сравнить с -O2 -NDEBUG -ftree-vectorize -fno-rtti -fno-exceptions -fomit-frame-pointer , и вы увидите, что std :: vector будет немного лучше, чем ваш код. GCC знает, что такое «встроенные» типы и как их использовать в реальном мире , и с радостью сделает это - так же, как он знает, что такое memset () и memcpy () выполняет и как оптимизировать соответственно, если известен размер копии.

7
ответ дан 3 December 2019 в 07:38
поделиться

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

Собираетесь ли вы компилировать свой код для выпуска только с -O0? Возможно нет. Вы также можете сравнить производительность алгоритмов при компиляции с любыми флагами компиляции, которые вы действительно собираетесь использовать.

6
ответ дан 3 December 2019 в 07:38
поделиться

У вас есть два алгоритма , реализованные на C ++. Если вы хотите сравнить относительную производительность двух реализаций, вам следует использовать уровень оптимизации, который вы собираетесь использовать в своем конечном продукте. Для меня это -O3 .

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

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

2
ответ дан 3 December 2019 в 07:38
поделиться

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

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

Лично я обычно используют -O2 с gcc. Мое общее практическое правило - использовать самый низкий уровень оптимизации, который включает автоматическое встраивание. Я пишу большую часть своего кода, ожидая, что небольшие функции будут встроены компилятором - и пишу код специально, чтобы помочь в этом (например, часто использую функторы вместо функций). Если компилятор не настроен на создание кода для этих встроенных, вы не получите то, что я действительно задумал. Производительность кода, когда он скомпилирован таким образом, на самом деле ничего не значит - я бы определенно не планировал когда-либо использовать его таким образом.

0
ответ дан 3 December 2019 в 07:38
поделиться

Я не вижу причин не компилировать и запускать их оба на O2. Если вы не делаете это как чисто академическое упражнение (и даже если бы вы так и сделали, то очень маловероятно, что оптимизации приведут к фундаментальным изменениям в свойствах алгоритма - хотя, я думаю, я был бы счастлив, если бы GCC начал переключать O (N) source в сборку O (lgN)), вам понадобится информация, согласованная с тем, что вы получили бы при фактическом запуске последней программы. Скорее всего, вы не будете выпускать программу с оптимизацией O0, поэтому вы не хотите сравнивать алгоритмы при оптимизации O0.

1
ответ дан 3 December 2019 в 07:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: