Оптимизация размера программы: самые большие функции/модули
От: malphunction  
Дата: 27.03.11 07:44
Оценка:
Портирую программу на платформу OpenWRT, она получается размером где-то 140Kb.
Мне необходимо уменьшить её хотя бы килобайт на 20-30. Для этого я решил:
а) найти большие функции, оптимизировать их размер.
б) минимизировать зависимости из stdlib и прочего.

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

Компилятор: GCC 4.x, процессор: Arm (портирую на роутер ASUS WL-520GU)

P.S.: -Os, -Wl,--gc-sections, strip и т.д. я применял; это реально помогает, но нужно
ещё сильнее уменьшить exe-шник
Re: Оптимизация размера программы: самые большие функции/мод
От: nen777w  
Дата: 28.03.11 22:12
Оценка:
M>а) как получить список самых больших функций, получившихся при компиляции?

Как вариант. Взять IDA Pro она умеет показывать функции и их размер, в том числе и дизасмить вашу архитектуру. Можно отсортировать и смотреть там.
Ещё наверно можно сгенерить map файл и по нему ориентироваться.

M>б) какие функции тянут из библиотек больше всего зависимостей?


кто ж это вам скажет не зная что у вас там внутри получилось. Сами смотрите.
Re: Оптимизация размера программы: самые большие функции/мод
От: chemey  
Дата: 30.03.11 07:38
Оценка: 1 (1)
Здравствуйте, malphunction, Вы писали:

M>Портирую программу на платформу OpenWRT, она получается размером где-то 140Kb.

M>Мне необходимо уменьшить её хотя бы килобайт на 20-30. Для этого я решил:
M>а) найти большие функции, оптимизировать их размер.
M>б) минимизировать зависимости из stdlib и прочего.

Насчет больших функций — согласен.
Насчет зависимостей из stdlib — не совсем понимаю. Что там может быть такого большого?

M>Подскажите, как это лучше всего сделать? Т.е.:

M>а) как получить список самых больших функций, получившихся при компиляции?

Map-файл получить тебе уже советовали. Это, конечно, штука хорошая, но разобраться в нем трудновато (и далеко не все в нем есть).

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

У этого метода, конечно, недостатки есть: длина включает паддинг, добавленный компилятором, и для последней функции длина остается непосчитанной (хотя можно и ее вычислить косвенными методами, но мне было лениво — там обычно .fini, она короткая).

Единственная проблема — работает ли objdump с бинарями под ARM.

M>P.S.: -Os, -Wl,--gc-sections, strip и т.д. я применял; это реально помогает, но нужно

M>ещё сильнее уменьшить exe-шник

Стрипать не обязательно — дебажные символы при старте программы в память не грузятся. Их отладчик грузит, когда под ним запускаешь.
Впрочем, если файл физически в роутер не влазит — тогда да
Бзззззззжжжжж
Re[2]: Оптимизация размера программы: самые большие функции/
От: Аноним  
Дата: 02.04.11 11:30
Оценка: 1 (1)
Здравствуйте, chemey, Вы писали:

C>Здравствуйте, malphunction, Вы писали:


M>>Портирую программу на платформу OpenWRT, она получается размером где-то 140Kb.

M>>Подскажите, как это лучше всего сделать? Т.е.:
M>>а) как получить список самых больших функций, получившихся при компиляции?

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


C>Единственная проблема — работает ли objdump с бинарями под ARM.


конечно работает, а как бы он по вашему с помощью gcc собрал программу, без binutils?
Re[2]: Оптимизация размера программы: самые большие функции/
От: malphunction  
Дата: 19.04.11 04:35
Оценка:
Спасибо за ответы.

Попробую с map-файлами и binutils.
Удивлен, что нет универсального решения, разве народ не занимается оптимизацией собственных программ по размеру?
Для встраиваемых решений это же ещё актуально.

C>Насчет зависимостей из stdlib — не совсем понимаю. Что там может быть такого большого?


Ошибся. Не stdlib, а шаблоны: мне нужны std::vector и std::string.
Тоже не ясно, как считать их размер? И стоит ли их как-то оптимизировать?
Я вот попытался написать свой аналог std::string на функциях strlen, strcat
и т.п. -- выигрыш составил пару процентов, не стоило и браться :(

C>Стрипать не обязательно — дебажные символы при старте программы в память не грузятся. Их отладчик грузит, когда под ним запускаешь.

C>Впрочем, если файл физически в роутер не влазит — тогда да :)

Да, мне именно размер исполнимого файла уменьшить, чтобы в роутер его засунуть.
Re[3]: Оптимизация размера программы: самые большие функции/
От: BulatZiganshin  
Дата: 19.04.11 05:36
Оценка:
Здравствуйте, malphunction, Вы писали:

M>Удивлен, что нет универсального решения, разве народ не занимается оптимизацией собственных программ по размеру?


это будет очень муторно. советую глядеть в сторону станд. функций. среди них могут быть очень большие универсальные: scanf, printf, I/O вообще. ещё можно заменить макросы (как getc/putc) на вызовы функций
Люди, я люблю вас! Будьте бдительны!!!
Re: Оптимизация размера программы: самые большие функции/мод
От: uzhas Ниоткуда  
Дата: 19.04.11 06:04
Оценка: +1
Здравствуйте, malphunction, Вы писали:

M>P.S.: -Os, -Wl,--gc-sections, strip и т.д. я применял; это реально помогает, но нужно

M>ещё сильнее уменьшить exe-шник
еще есть такой момент : обычно если тянется функция из .obj, то obj целиком линкуется в ехе (это дефолтное поведение gcc + vs).
в этом случае мы в компании стараемся распилить .cpp на два исходника таким образом, чтобы при линковке потребовался лишь один .obj
поэтому рекомендую вам оценить объем кода, который никогда не используется в ехе и попробовать его убрать из финального .ехе
это несложно сделать, так как у мейнстрим компиляторов есть опции, которые заставляют линкер вычищать мертвый код (время линковки может заметно вырасти)
можно еще coverage посчитать спец. утилитами
успехов
Re[2]: Оптимизация размера программы: самые большие функции/
От: malphunction  
Дата: 19.04.11 06:15
Оценка: 1 (1)
Здравствуйте, uzhas, Вы писали:

U>еще есть такой момент : обычно если тянется функция из .obj, то obj целиком линкуется в ехе (это дефолтное поведение gcc + vs).

....
U>это несложно сделать, так как у мейнстрим компиляторов есть опции, которые заставляют линкер вычищать мертвый код (время линковки может заметно вырасти)

Так а я сразу компилирую с параметрами: -fdata-sections -ffunction-sections
А потом линкую: -s -Wl,--gc-sections

Вырезает всё мёртвое.

Время компиляции/компоновки замедляется, но прожка небольшая, так что эффект мал.
Re[3]: Оптимизация размера программы: самые большие функции/
От: Sanik Россия http://sergeysthoughts.blogspot.com/
Дата: 20.04.11 06:32
Оценка: +1
Здравствуйте, malphunction, Вы писали:

M>Так а я сразу компилирую с параметрами: -fdata-sections -ffunction-sections

M>А потом линкую: -s -Wl,--gc-sections

M>Вырезает всё мёртвое.


M>Время компиляции/компоновки замедляется, но прожка небольшая, так что эффект мал.


Попробуйте добавить

-fno-exceptions -fno-rtti

Должно дать немного выигрыша по размеру.
Вы, кстати, уже попробовали что-то маленькое на C++ запустить на рутере?
Я сталкивался с проблемой, отсуствия libstdc++.so (рантайма) на устройстве, что сводит на нет все попытки написания на C++.
... << RSDN@Home 1.2.0 alpha 4 rev. 1477>>
Re[4]: Оптимизация размера программы: самые большие функции/
От: _nn_ www.nemerleweb.com
Дата: 21.04.11 17:05
Оценка:
Здравствуйте, Sanik, Вы писали:

S>Должно дать немного выигрыша по размеру.

S>Вы, кстати, уже попробовали что-то маленькое на C++ запустить на рутере?
S>Я сталкивался с проблемой, отсуствия libstdc++.so (рантайма) на устройстве, что сводит на нет все попытки написания на C++.

Не все потеряно: static libstdc++.

Правда, с размером тут не гарантировано конечно.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Оптимизация размера программы: самые большие функции/
От: _nn_ www.nemerleweb.com
Дата: 21.04.11 17:13
Оценка:
Здравствуйте, malphunction, Вы писали:

M>Спасибо за ответы.


M>Попробую с map-файлами и binutils.

M>Удивлен, что нет универсального решения, разве народ не занимается оптимизацией собственных программ по размеру?
M>Для встраиваемых решений это же ещё актуально.

C>>Насчет зависимостей из stdlib — не совсем понимаю. Что там может быть такого большого?


M>Ошибся. Не stdlib, а шаблоны: мне нужны std::vector и std::string.


Чем больше методов у шаблонного класса используются, тем больше кода добавляется
Если vector используется для разных типов, то возможно компилятор не может оптимизировать все методы.

M>Тоже не ясно, как считать их размер? И стоит ли их как-то оптимизировать?


M>Я вот попытался написать свой аналог std::string на функциях strlen, strcat

M>и т.п. -- выигрыш составил пару процентов, не стоило и браться

Вероятно есть libstdc++.so и реализация std::string береться оттуда.

Как вариант, попробуйте использовать больше библиотечных функций.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Оптимизация размера программы: самые большие функции/
От: sz36 Россия  
Дата: 21.04.11 19:24
Оценка:
Здравствуйте, malphunction, Вы писали:

M>Удивлен, что нет универсального решения, разве народ не занимается оптимизацией собственных программ по размеру?

M>Для встраиваемых решений это же ещё актуально.
Неа. На практически любой кристалл сейчас есть такой же, но с удвоенным размером памяти и на несколько копеек дороже, несопоставимо с зарплатой программиста. 140кб для АРМ — довольно-таки смешной размер.

По сути — наиболее эффективным будет избавится от printf, scanf и поддержки плавающей точки, если есть возможность. Ну и алгоритмическая оптимизация, если, опять же, есть возможность. Остальные способы дадут гроши.
Re[4]: Оптимизация размера программы: самые большие функции/
От: malphunction  
Дата: 22.04.11 00:46
Оценка:
Здравствуйте, sz36, Вы писали:

S>Здравствуйте, malphunction, Вы писали:


M>>Удивлен, что нет универсального решения, разве народ не занимается оптимизацией собственных программ по размеру?

M>>Для встраиваемых решений это же ещё актуально.
S> Неа. На практически любой кристалл сейчас есть такой же, но с удвоенным размером памяти и на несколько копеек дороже, несопоставимо с зарплатой программиста. 140кб для АРМ — довольно-таки смешной размер.

Согласен; но моя проблема в том, что приходится писать под конкретную модель роутера;
после установки всех необходимых программ там остается вот те самые 140-160 Kb :(

S> По сути — наиболее эффективным будет избавится от printf, scanf.


А scanf и printf библиотечные же? Из libc, которая есть на роутере. Есть ли
смысл от них избавляться?
Re[4]: Оптимизация размера программы: самые большие функции/
От: malphunction  
Дата: 22.04.11 00:50
Оценка:
Здравствуйте, Sanik, Вы писали:

S>Попробуйте добавить

S>-fno-exceptions -fno-rtti

Да, от rtti можно избавиться, сегодня попробую. А вот exception'ы
в одном модуле задействованы, попробую их убрать.

S>Должно дать немного выигрыша по размеру.

S>Вы, кстати, уже попробовали что-то маленькое на C++ запустить на рутере?
S>Я сталкивался с проблемой, отсуствия libstdc++.so (рантайма) на устройстве, что сводит на нет все попытки написания на C++.

Да, моя программа на C++ (в том смысле, что использует std::* и несколько самописных классов, но без
других сишных наворотов). Если линковать динамически с libstdc++.so, то прога получается маленькой
(где-то 30 Kb), но сама библиотека не влезает в роутер :( Поэтому я использую статическую линковку,
как ниже предлагали. Прогу разбабахивает до 150-200 Kb. А это уже много.
Re[5]: Оптимизация размера программы: самые большие функции/
От: Sanik Россия http://sergeysthoughts.blogspot.com/
Дата: 22.04.11 04:56
Оценка:
Здравствуйте, malphunction, Вы писали:

M>Здравствуйте, Sanik, Вы писали:


S>>Попробуйте добавить

S>>-fno-exceptions -fno-rtti

M>Да, от rtti можно избавиться, сегодня попробую. А вот exception'ы

M>в одном модуле задействованы, попробую их убрать.

S>>Должно дать немного выигрыша по размеру.

S>>Вы, кстати, уже попробовали что-то маленькое на C++ запустить на рутере?
S>>Я сталкивался с проблемой, отсуствия libstdc++.so (рантайма) на устройстве, что сводит на нет все попытки написания на C++.

M>Да, моя программа на C++ (в том смысле, что использует std::* и несколько самописных классов, но без

M>других сишных наворотов). Если линковать динамически с libstdc++.so, то прога получается маленькой
M>(где-то 30 Kb), но сама библиотека не влезает в роутер Поэтому я использую статическую линковку,
M>как ниже предлагали. Прогу разбабахивает до 150-200 Kb. А это уже много.

Это собсвенно и есть основная проблема диетизации
Как неоригинальный вариант — избавиться от C++ зависимостей с помощью данной библиотеки и переделкой под C.
... << RSDN@Home 1.2.0 alpha 4 rev. 1477>>
Re[5]: Оптимизация размера программы: самые большие функции/
От: sz36 Россия  
Дата: 22.04.11 21:04
Оценка:
Здравствуйте, malphunction, Вы писали:

M>Согласен; но моя проблема в том, что приходится писать под конкретную модель роутера;

M>после установки всех необходимых программ там остается вот те самые 140-160 Kb
Так если там ОС стоит, то с большой вероятностью в ней можно чего-нибудь "почикать". Пользуясь терминологией нашего, прости Господи, национального лидера. 30 кило совсем немного — может картинка какая, или ReadMe, или еще что-нибудь ненужное...

M>А scanf и printf библиотечные же? Из libc, которая есть на роутере.

Так Вы пишете, что статическую линковку используете? scanf и printf много за собой тянут, в частности, поддержку ПЗ (если она у Вас не используется).
Re[6]: Оптимизация размера программы: самые большие функции/
От: malphunction  
Дата: 23.04.11 04:14
Оценка:
Здравствуйте, sz36, Вы писали:

S> Так если там ОС стоит, то с большой вероятностью в ней можно чего-нибудь "почикать". Пользуясь терминологией нашего, прости Господи, национального лидера. 30 кило совсем немного — может картинка какая, или ReadMe, или еще что-нибудь ненужное...


Почищено всё; даже комментарии из системных скриптов выпилены.

M>>А scanf и printf библиотечные же? Из libc, которая есть на роутере.

S> Так Вы пишете, что статическую линковку используете? scanf и printf много за собой тянут, в частности, поддержку ПЗ (если она у Вас не используется).

Я статически линкую только libstdc++ (в другой ветке объяснено, почему), а libc есть на роутере -- с ней линкуюсь динамически.
Поэтому использование scanf/printf не раздувает прогу, как я понимаю.

Что такое ПЗ -- не понял.
Re[5]: Оптимизация размера программы: самые большие функции/
От: Zhendos  
Дата: 23.04.11 11:53
Оценка:
Здравствуйте, malphunction, Вы писали:

M>Здравствуйте, Sanik, Вы писали:


M>Да, моя программа на C++ (в том смысле, что использует std::* и несколько самописных классов, но без

M>других сишных наворотов). Если линковать динамически с libstdc++.so, то прога получается маленькой
M>(где-то 30 Kb), но сама библиотека не влезает в роутер Поэтому я использую статическую линковку,
M>как ниже предлагали. Прогу разбабахивает до 150-200 Kb. А это уже много.

Тогда смысл разбираться с программой если она состовляет максимум 20% от бинарника?

По моему мнению ситуация следующая есть набор объектных файлов твоей программы,
собранных с ffunction-section, есть libstdc++.a — архив с объектныыми файлами
библиотеки C++, которые не собраны с ffunction-section, соотвественно,
когда происходит линковка самые большие куски не нужного тебе кода не выбрасываются.
И по-моему решение очевидно.
Re: Оптимизация размера программы: самые большие функции/мод
От: Xeor Россия  
Дата: 23.04.11 19:33
Оценка:
Здравствуйте, malphunction, Вы писали:


M>Компилятор: GCC 4.x, процессор: Arm (портирую на роутер ASUS WL-520GU)


Может, все-таки, mips?

А как со сжатием? OpenWRT чем-нибудь жмет свою прошивку?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.