Оптимизация обратной связи компилятора C/C++

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

  • Лучшие оценки развития.
  • Лучшие тестовые оценки.
  • Более быстрое время разработки.
  • Меньше общих ошибок.
  • Меньше связи между модулями.
  • Раньше выяснялось, неумышленно ли мой код что-то сломал.
  • и многое другое

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

Надеюсь, это поможет.

8
задан Rich 17 August 2016 в 14:30
поделиться

3 ответа

10% - хороший примерный показатель. Тем не менее, ...

Вы должны ДЕЙСТВИТЕЛЬНО заботиться о производительности, чтобы пойти по этому пути. Продукт, над которым я работаю (DB2), использует PGO и другие агрессивные и агрессивные оптимизации. Среди затрат - значительное время сборки (утроенное на некоторых платформах) и кошмары разработки и поддержки.

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

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

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

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

Из unladen-swallow (проект, оптимизирующий виртуальную машину CPython):

Для нас последний гвоздь в гроб PyBench был, когда мы экспериментировали с инструментами оптимизации gcc, ориентированными на обратную связь, мы смогли создать универсальное увеличение производительности на 15% по всем нашим макробенчмаркам; используя ту же тренировочную нагрузку, PyBench стал на 10% медленнее.

Так что некоторые люди по крайней мере смотрят на него. Тем не менее, PGO устанавливает некоторые довольно сложные требования к среде сборки, которые трудно удовлетворить для проектов с открытым исходным кодом, предназначенных для создания распределенной разнородной группой людей. Тяжелая оптимизация также затрудняет отладку heisenbugs. Менее трудоемко давать компилятору явные подсказки для критически важных частей.

Тем не менее, я ожидаю значительного увеличения производительности от оптимизации под руководством профиля времени выполнения. JIT ' Это позволяет оптимизатору справляться с профилем изменения данных в процессе выполнения программы и выполнять множество оптимизаций, особенно специфичных для данных во время выполнения, которые увеличивают размер кода для статической компиляции. Для хорошей работы динамические языки особенно нуждаются в хорошей оптимизации на основе данных во время выполнения. Поскольку в последнее время большое внимание уделяется производительности динамического языка (виртуальные машины JavaScript, MS DLR, JSR-292, PyPy и т. Д.), В этой области проводится большая работа

.
3
ответ дан 5 December 2019 в 17:38
поделиться

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

Мы можем полагаться на статистические данные для выполнения определенной оптимизации. Например, GCC разворачивает цикл, если количество циклов меньше константы (скажем, 7). То, как он исправляет константу, будет основано на статистическом результате размера кода, сгенерированного для различной целевой архитектуры.

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

Однако эксперименты в этом отношении продолжаются. Взгляните на POGO .

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

Однако эксперименты в этом отношении продолжаются. Взгляните на POGO .

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

Однако эксперименты в этом отношении продолжаются. Взгляните на POGO .

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

Однако эксперименты в этом отношении продолжаются. Взгляните на POGO .

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

Однако эксперименты в этом отношении продолжаются. Взгляните на POGO .

1
ответ дан 5 December 2019 в 17:38
поделиться