Практика кодирования, которая позволяет компилятору / оптимизатору создавать более быструю программу - PullRequest
116 голосов
/ 15 января 2010

Много лет назад компиляторы C не были особенно умными. В качестве обходного пути K & R изобрел ключевое слово register , чтобы намекнуть компилятору, что, возможно, было бы неплохо сохранить эту переменную во внутреннем регистре. Они также сделали третичный оператор, чтобы помочь генерировать лучший код.

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

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

Какие существуют методы кодирования, которые могут позволить компилятору / оптимизатору генерировать более быстрый код?

  • Буду признателен за указание используемой вами платформы и компилятора.
  • Почему техника работает?
  • Пример кода приветствуется.

Вот связанный вопрос

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

[Изменить] Ссылка, связанная со смещением

Ответы [ 32 ]

2 голосов
/ 15 января 2010

Если у вас есть небольшие функции, которые вы вызываете неоднократно, в прошлом я получал большие выгоды, помещая их в заголовки как «статические inline». Вызовы функций на ix86 удивительно дороги.

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

2 голосов
/ 17 января 2010

Когда DEC выпустил свои альфа-процессоры, было рекомендовано сохранить количество аргументов для функции до 7, так как компилятор всегда будет пытаться поместить до 6 аргументов в регистры автоматически.

2 голосов
/ 16 января 2010

Вот мой второй совет по оптимизации. Как и в случае с моим первым советом, это общее назначение, а не язык или процессор.

Внимательно прочитайте руководство по компилятору и поймите, что оно говорит вам. Используйте компилятор в полную силу.

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

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

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

Привет

Mark

Когда я впервые беру часть кода, я обычно могу получить производительность в 1,4-2,0 раза больше (т.е. новая версия кода работает в 1 / 1,4 или 1/2 от времени старой версии). ) в течение дня или двух, возясь с флагами компилятора. Конечно, это может быть комментарий о нехватке компилятора среди ученых, создавших большую часть кода, над которым я работаю, а не симптом моего превосходства. Установив флаги компилятора на максимум (а это редко просто -O3), может потребоваться месяцы кропотливой работы, чтобы получить другой коэффициент 1,05 или 1,1

1 голос
/ 16 января 2010

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

Предположим, что программа была написано правильно, составлено с полным оптимизация, протестирована и введена в производство.

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

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

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

1 голос
/ 16 января 2010

Я использую компилятор Intel. как на Windows, так и на Linux.

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

если код является вычислительным и содержит много циклов - отчет о векторизации в компиляторе Intel очень полезен - поищите в справке vec-report.

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

1 голос
/ 02 апреля 2010

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

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

1 голос
/ 15 января 2010

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

Оптимизатор поможет незначительно повысить производительность вашей программы.

1 голос
/ 17 января 2010

Одна оптимизация, которую я использовал в C ++, - это создание конструктора, который ничего не делает. Нужно вручную вызвать init (), чтобы перевести объект в рабочее состояние.

Это имеет преимущество в случае, когда мне нужен большой вектор этих классов.

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

Когда я генерирую объекты для заполнения вектора, я устанавливаю их с помощью init (). Это ограничивает общее количество ошибок на странице и избавляет от необходимости использовать resize () вектора при его заполнении.

0 голосов
/ 26 мая 2011

Поместите маленькие и / или часто вызываемые функции вверху исходного файла. Это облегчает компилятору поиск возможностей для встраивания.

0 голосов
/ 16 января 2010

Я давно подозревал, но никогда не доказывал, что объявление массивов так, чтобы они содержали степень 2, как число элементов, позволяет оптимизатору сделать уменьшение прочности , заменив умножение на смещение на количество бит при поиске отдельных элементов.

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