Есть ли какие-либо инструменты для того, чтобы разыскать чрезмерное увеличение размера в C++?

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

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

Я очень не интересуюсь производительностью на этой точке - это - все о размере исполняемого файла.

Есть ли какие-либо инструменты для этого задания, применимого в Windows, и соответствующий или MinGW GCC или Visual Studio?

РЕДАКТИРОВАНИЕ - некоторый контекст

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

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

Разделенный на уровни сверху тех, у меня есть некоторые более сложные контейнеры, такие как двухсторонние карты. Вдобавок к тем у меня есть классы диграфа и дерево. Вдобавок к тем...

Используя файлы карты, я мог разыскать, вызывают ли невстроенные шаблонные методы чрезмерное увеличение размера. Это - просто вопрос нахождения всех инстанцирований конкретного метода и добавления размеров. Но что относительно неблагоразумно встроенных методов? Шаблоны были, в конце концов, предназначены, чтобы быть тонкими обертками вокруг некода шаблона, но исторически моя способность судить, должно ли что-то быть встроено или не не было очень надежно. Влияние чрезмерного увеличения размера тех обрабатывает по шаблону, встраивает, не так легко иметь размеры.

У меня есть некоторая идея, какие методы в большой степени используются, но это - известная ошибка opimization без профилирования.

7
задан templatetypedef 3 November 2013 в 21:29
поделиться

4 ответа

Проверить Сортировка символов . Я использовал его некоторое время назад, чтобы выяснить, почему наш установщик вырос в 4 раза за шесть месяцев (оказывается, ответом было статическое связывание среды выполнения C и libxml2).

7
ответ дан 6 December 2019 в 12:46
поделиться

Анализ файла карты

Некоторое время назад я видел подобную проблему, и в итоге я написал специальный инструмент, который анализировал файл карты (компоновщик Visual Studio может получить указание на его создание) . Результатом инструмента было:

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

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

Вот небольшой отрывок из файла карты, чтобы вы знали, чего ожидать:

Address         Publics by Value              Rva+Base       Lib:Object

0001:0023cbb4       ?ApplyScheme@Input@@QAEXPBVParamEntry@@@Z 0063dbb4 f   mainInput.obj
0001:0023cea1       ?InitKeys@Input@@QAEXXZ    0063dea1 f   mainInput.obj
0001:0023cf47       ?LoadKeys@Input@@QAEXABVParamEntry@@@Z 0063df47 f   mainInput.obj

Сортировка по символам

Как указано в Ответ Бена Стауба , Сортировка по символам - это готовая к использованию утилита командной строки (поставляется с полным исходным кодом C #), которая делает все это, с той лишь разницей, что анализирует не файлы карты, а файлы pdb / exe.

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

По сути, вы ищете дорогостоящие вещи, которые вам не нужны. Предположим, что существует некоторая категория функций, которые вам не нужны, занимающая какой-то большой процент пространства, например 20%. Тогда если вы выберете 20 случайных байт из размера изображения, в среднем 4 из них (20 * 20%) будут в этой категории, и вы сможете их увидеть. Итак, в основном, вы берете эти образцы, смотрите на них, и если вы видите очевидный паттерн функций, которые вам на самом деле не нужны, то удалите их. Затем сделайте это снова, потому что другие категории процедур, которые использовали меньше места, теперь занимают больший процент.

Поэтому я согласен с Сумой, что разбор файла карты - это хорошее начало. Затем я бы написал процедуру, чтобы пройтись по ней, и каждые 5% пути (с точки зрения пространства) печатать процедуру, в которой я нахожусь. Таким образом, я получу 20 образцов. Часто я обнаруживаю, что большой кусок объектного пространства возникает из-за очень малого числа (например, 1) строк исходного кода, которые я мог бы легко сделать другим способом.

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

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

Удачи.

1
ответ дан 6 December 2019 в 12:46
поделиться

Итак, что я читаю на основании вашего вопроса и ваших комментариев, так это то, что библиотека , а не на самом деле слишком велика.

Единственный инструмент, который вам нужен, чтобы определить это, - это командная оболочка или проводник Windows. Посмотрите на размер файла.Неужели он настолько велик, что вызывает реальные проблемы? (Неприемлемое время загрузки, не помещается в памяти на целевой платформе и тому подобное)?

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

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

Однако, если предположить, что размер файла составляет , на самом деле проблема:

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

Если вас беспокоит, что встроенные функции вызывают раздувание кода, просто скомпилируйте с флагом «оптимизировать по размеру». Затем компилятор ограничит встраивание случаями, когда это не влияет заметно на размер исполняемого файла.

Чтобы узнать, какие символы самые большие, проанализируйте файл карты, как предложено @Suma.

Но на самом деле, вы сами это сказали, когда упомянули «известную ошибку оптимизации без профилирования.«

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

Профиль. Соберите данные и выявляйте проблемные места. Прежде чем беспокоиться о том, как уменьшить размер исполняемого файла, выясните, каков размер исполняемого файла , и определите, действительно ли это проблема. Вы еще этого не сделали. В книге вы читали, что «раздувание кода - проблема C ++», и поэтому вы предполагаете, что раздувание кода - это проблема вашей программы. но так ли? Почему? Как вы это определяете?

2
ответ дан 6 December 2019 в 12:46
поделиться
Другие вопросы по тегам:

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