Каковы некоторые методы или инструменты для профилирования избыточного размера кода в приложениях C / C ++? - PullRequest
5 голосов
/ 13 октября 2009

У меня есть библиотека C ++, которая генерирует гораздо больший код, который я действительно ожидал бы от того, что он делает. Из менее чем 50 тыс. Строк исходного кода я получаю общие объекты размером почти 4 МБ и статические архивы, загружающие 9. Это проблематично, поскольку двоичные файлы библиотеки достаточно велики, и, что гораздо хуже, даже простые приложения, ссылающиеся на него, обычно получают от 500 до 1000 КБ в размере кода. Компиляция библиотеки с такими флагами, как -Os, несколько помогает, но не очень.

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

Есть ли какой-нибудь инструмент, который позволяет легко профилировать размер кода, или каким-то другим способом, которым я могу выяснить, что занимает так много места, или, вообще, какие-либо другие вещи, которые я должен попробовать? Что-то, что работает под Linux, было бы идеально, но я возьму то, что смогу получить.

Ответы [ 3 ]

7 голосов
/ 13 октября 2009

Если вы хотите узнать, что помещается в ваш исполняемый файл, спросите ваши инструменты. Включите опцию lprint linker --print-map (или -M), чтобы создать файл карты, показывающий, что он поместил в память и где. Выполнение этого для статического связанного примера, вероятно, более информативно.

Если вы не вызываете ld напрямую, а только через командную строку gcc, вы можете передать ld определенные параметры ld из командной строки gcc, поставив перед ними -Wl,.

2 голосов
/ 14 октября 2009

В Linux компоновщик, безусловно, объединяет несколько шаблонов.

Убедитесь, что вы не измеряете двоичные файлы отладки (отладочная информация может занимать более 75% окончательного двоичного размера).

Один из способов уменьшить конечный двоичный размер - это скомпилировать с -ffunction-sections и -fdata-sections, а затем связать с -Wl,--gc-sections.

Еще большее сокращение (мы видели 25%) может быть возможным, если вы используете версию для разработки [gold][1] (новый компоновщик только для ELF, часть binutils) и ссылку с -Wl,--icf

Еще один полезный прием - сокращение набора символов, которые «экспортируются» вашими общими библиотеками (все экспортируется по умолчанию), либо через __attribute__((visibility(...))), либо с помощью сценария компоновщика. Подробности здесь (см. «Экспортный контроль»).

1 голос
/ 14 октября 2009

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

.
...