- PVSM.RU - https://www.pvsm.ru -

GCC x86, как уменьшить размер кода

GCC x86, как уменьшить размер кода      Времена, когда программисты пытались выжать максимум из размера своего приложения, безвозвратно ушли. Основной причиной является существенное увеличение объемов оперативной памяти и дискового простраства на современных компьютерах. Немногие помнят, как при загрузке приложения с кассеты можно было пойти покушать. Или как можно было считать моргания дисковода, косвенно определяя размер приложения. Пожалуй, только разработчики програмного обеспечения под встраиваемые системы до сих пор заботятся о размере кода и потребляемой памяти. Могут ли таблетки и смартфоны вернуть разработчиков «назад в будущее»?
      Данная статья призвана помочь разработчикам програмного обеспечения, испульзующим GCC компилятор, уменьшить размер кода своих приложений. Все данные в статье получены при помощи x86 GCC компилятора версии 4.7.2 на операционной система Fedora 17 для архитектуры Intel® Atom™.

      Довольно существенный выигрыш с точки зрения размера GCC дает динамическая линковка (включенная по умолчанию). То, насколько динамическая линковка выигрывает у стаитической, сильно зависит от используемых библиотек.
      Чаще всего, когда речь заходит об оптимизации размера, используется опция “-Os”. Ниже приведена табличка со средними геометрическими размера кода по набору приложений для смартфонов и таблеток.
      Результаты в табличке показаны относительно “-Os”. Меньший результат говорит о меньшем размере кода. “-m32, -mfpmath=sse, -march=atom” включены по-умолчанию во всех случаях.

-O2 6%
-O2 -flto -5%
-Ofast 11,5%
-Ofast -flto 3%
-Ofast -funroll-loops 19%
-Ofast -funroll-loops -flto 10,5%

      “-Ofast” (или “-O3”) и “-funroll-loops”, очевидно, увеличивают размер кода. Опция “-flto”, за счет более агрессивной подстановки функций (inline), также должна увеличивать размер кода. Однако, результат противоположный. Почему?
      “-flto” делает возможным удаление неиспользуемых функций. Функция может стать таковой, если в конкретной конфигурации приложения она не вызывается или была полностью и во всех местах вызова подставлена в код. Для того, чтобы удалить неиспользуемые функции без “-flto” можно воспользоваться “-ffunction-sections -Wl,--gc-sections”. Данная техника дает хороший результат, если в приложении используются внутренние статические библиотеки.
      Приложение все еще слишком большое? Есть еще несколько техник для уменьшения размера. По умолчанию GCC использует опцию “-fasynchronous-unwind-tables”, что увеличивает размер EH (exception handling) секции, даже при компиляции приложений на языке “C”. Это облегчает процесс отладки, однако может существенно увеличить размер кода. Для отключения надо добавить “-fno-asynchronous-unwind-tables” к опциям компиляции.
      “-Wl,--strip-all” сообщит линкеру, что надо удалить всю символьную информацию. Это сделает процесс отладки еще сложнее. И все же, если размер кода критичен, опция приемлема.
      Ниже приведена табличка отражающая эффект от добавления:

  • “-ffunction-sections -Wl,--gc-sections” (+ сборщик мусора)
  • “-ffunction-sections -Wl,--gc-sections -fno-asynchronous-unwind-tables” (+ без таблиц раскрутки)
  • “-ffunction-sections -Wl,--gc-sections -fno-asynchronous-unwind-tables -Wl,--strip-all” (+ удаление символов)

      к различным опциям оптимизации.

      Результаты в табличке показаны относительно “-Os”. Меньший результат говорит о меньшем размере кода. “-m32, -mfpmath=sse, -march=atom” включены по-умолчанию во всех случаях.

по умолчанию + сборщик мусора + без таблиц раскрутки + удаление символов
-Os - -5% -10,5% -22,5%
-O2 6% 0,5% -3,5% -13,5%
-O2 -flto -5% -5% -8% -17%
-Ofast 11,5% 6% 2% -6,5%
-Ofast -flto 3% 2,5% 0,5% -6,5%
-Ofast -funroll-loops 19% 12,5% 9,5% 3%
-Ofast -funroll-loops -flto 10,5% 10% 8,5% 2,5%

      Ниже представлено описание используемых в статье опций компилятора. Полное описание (на английском): gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Optimize-Options.html [1]

  • "-Ofast" аналогично "-O3 -ffast-math" включает более высокий уровень оптимизаций и более агрессивные оптимизации для арифметических вычислений (например, вещественную реассоциацию)
  • "-flto" межмодульные оптимизации
  • "-m32" 32 битный режим
  • "-mfpmath=sse" включает использование XMM регистров в вещественной арифметике (вместо вещественного стека в x87 режиме)
  • "-funroll-loops" включает развертывание циклов
  • "-ffunction-sections" размещает каждую функцию в отдельной секции
  • "-Os" оптимизирует производительность и размер
  • "-fno-asynchronous-unwind-tables" гарантирует точность таблиц раскрутки только в пределах функции

      Ниже представлено описание используемых в статье опций линковщика. Полное описание (на английском): sourceware.org/binutils/docs/ld/Options.html [2]

  • “--gc-sections” включает удаление неиспользуемых секций
  • “--strip-all” удаляет символьную информацию

Автор: Evgeny1982

Источник [3]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/programmirovanie/25859

Ссылки в тексте:

[1] gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Optimize-Options.html: http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Optimize-Options.html

[2] sourceware.org/binutils/docs/ld/Options.html: http://sourceware.org/binutils/docs/ld/Options.html

[3] Источник: http://habrahabr.ru/post/167417/