Как я могу заставить свою очень большую программу связываться?

Наш следующий продукт стал слишком большим для соединения на машине, запускающей 32-разрядный Windows. Суммарный итог всех библиотечных файлов превышает 2 ГБ и может только быть связан на 64-разрядной машине Windows. В конечном счете мы превысим ту границу, так как наше программное обеспечение имеет тенденцию расти, а не сокращаться, и мы используем 32-разрядного компоновщика (Visual Studio MS 2005): мы ожидаем поражать проблему, когда наше общее количество размера lib превысит 3 ГБ.

Как я могу уменьшить размер .lib файлов или .obj файлов, не обрезая код? Например, мы используем много шаблонов: есть ли какой-либо способ уменьшить их место? Есть ли какой-либо способ узнать то, что вызывает чрезмерное увеличение размера от исследования .lib/.obj файлов? Это может быть автоматизировано, а не осмотрено глазом? 2.5 ГБ являются большим количеством текста, чтобы взаимодействовать через и выдержать сравнение.

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

9
задан hatcat 22 July 2010 в 13:15
поделиться

8 ответов

Попробуйте использовать программу Symbol Sort, которая покажет вам, где в вашем коде находятся основные биты раздутости. Также просто посмотрите на размер необработанных .obj-файлов - это даст вам разумное представление о том, куда направить усилия.

3
ответ дан 4 December 2019 в 11:39
поделиться

Однажды я работал над проектом с несколькими MLoC. В то время как наш по-прежнему будет связываться на 32-битной машине, время связывания было ужасным и стало серьезной проблемой, потому что разработчикам приходилось выполнять только дюжину циклов редактирования-компиляции-тестирования за рабочий день. (Время компиляции было довольно хорошо обработано за счет выполнения распределенной компиляции.)

Мы перешли на динамическое связывание. Это увеличило время запуска, но с этим можно было справиться, отложив загрузку библиотек DLL.

5
ответ дан 4 December 2019 в 11:39
поделиться

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

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

Наконец, я знаю, что Visual Studio (или, возможно, Windows SDK) имеет 64-битный компилятор (то есть компилятор, который сам является 64-битным приложением, а не просто компилятором, производящим 64-битный код). Подумайте об использовании этого. (Я не знаю, существует ли еще 64-битный компоновщик)

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

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

5
ответ дан 4 December 2019 в 11:39
поделиться

OMFG !!!!! Это ууууууге!

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

2
ответ дан 4 December 2019 в 11:39
поделиться

Это должно быть одно большое приложение?

Один из вариантов - разделить различные модули на библиотеки DLL и загрузить / выгрузить их по мере необходимости.

В качестве альтернативы вы можете разделить на несколько приложений и обмениваться данными с использованием отображаемой памяти, конвейера СУБД или даже простых файлов данных.

2
ответ дан 4 December 2019 в 11:39
поделиться

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

Выполните

dumpbin /HEADERS <somebinary>

, чтобы выяснить, какие разделы в вашем бинарном файле вызывают огромный размер. Есть ли у вас огромный раздел Debug Directory? Удалите символы. Велика ли таблица адресов импорта? Проверьте таблицу и найдите ненужные символы (проблема с шаблонами заключается в том, что символы инстанций шаблонов имеют тенденцию быть очень большими). Аналогичный анализ можно провести для каталога исключений, каталога дескрипторов COM и т.д..

2
ответ дан 4 December 2019 в 11:39
поделиться

Я не думаю, что существует какой-то один инструмент, который может дать вам статистику, которая вам нужна. Использование файлов .map или утилиты dumpbin с параметром /SYMBOLS плюс некоторая постобработка созданного журнала может помочь вам получить то, что вы хотите.

Если статистика подтвердит ваши подозрения о раздутости шаблонов, или даже без подтверждения, возможно, будет хорошей идеей сделать несколько вещей с исходниками:

  1. Попробуйте использовать явные инстансы и перенести определения шаблонов в .cpp файлы. Конечно, это работает, только если у вас есть ограниченный и хорошо известный набор типов/значений, которые вы используете в качестве аргументов для шаблонов.
  2. Добавьте больше абстракции и/или косвенности. Выделите код, который не зависит от параметров шаблона, в собственные базовые классы или свободные функции. Если у вас есть несколько параметров типа шаблона, посмотрите, нельзя ли разбить шаблон одного класса на несколько базовых классов без перекрывающихся параметров шаблона. (См. http://www2.research.att.com/~bs/SCARY.pdf.)
  3. Попробуйте использовать идиому pimpl; по возможности избегайте инстанцирования шаблонов в заголовках, инстанцируйте их только в файлах .cpp.
  4. Шаблоны - это хорошо, но иногда обычные классы работают не хуже; например, избегайте передачи целочисленных констант в качестве параметров шаблона, если вы можете передать их как параметр в ctor.
0
ответ дан 4 December 2019 в 11:39
поделиться

Я очень скептически отношусь к тому, что ваш реальный код составляет 2 ГБ; скорее всего, вы собираете много информации. Рассмотрите возможность выгрузки части этой информации в файл ресурсов и встраивания ее в исполняемый файл в качестве отдельного шага.

-1
ответ дан 4 December 2019 в 11:39
поделиться
Другие вопросы по тегам:

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