Как мне получить ссылку на мою очень большую программу? - PullRequest
9 голосов
/ 22 июля 2010

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

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

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

Ответы [ 9 ]

5 голосов
/ 22 июля 2010

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

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

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

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

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

5 голосов
/ 22 июля 2010

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

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

3 голосов
/ 22 июля 2010

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

2 голосов
/ 22 июля 2010

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

Run

dumpbin /HEADERS <somebinary>

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

2 голосов
/ 22 июля 2010

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

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

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

2 голосов
/ 22 июля 2010

OMFG !!!!!Это huuuuuge!

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

0 голосов
/ 04 октября 2017

@ hatcat и @jalf: действительно, существует полный набор 64-битных инструментов .Например, вы можете установить переменную среды:

set PreferredToolArchitecture=x64

и затем запустить Visual Studio (из консоли разработчика).

0 голосов
/ 22 июля 2010

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

0 голосов
/ 22 июля 2010

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

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

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