Comments 43
Немногие помнят, как при загрузке приложения с кассеты можно было пойти покушать.Ну, фотошоп и некоторые другие тяжёлые приложения и до сих пор так грузятся :)
+11
Это конечно перебор, на современных компьютерах даже с HDD успеваешь только чайник включить :)
0
Пока я не поставил SSD, вполне успевал съесть бутерброд или два, пока загрузятся ОС и приложения в автозагрузке.
0
Выходит, SSD полезны для здоровья? :)
+7
Наоборот — приложения стартуют за секунду, на еду не остаётся времени, и от нерегулярного питания можно заработать гастрит.
+14
UFO just landed and posted this here
Цифры интересные, но несколько не понятно, какой будет результат на разных проектах. Уж точно не те же проценты от объема бинарников. Думаю, будет полезно показать код, который оптимизировался в ходе работа на статьей.
0
С месяц назад пытался выжать из своего мини-приложения самый маленький размер. При включенной опции "-О2" выжал 3.5kb, при "-О1" — 3kb. Все опции из статьи использованы. + Ещё склеивал секции .text и .rdata с помощью скрипта линковщика. Но компилятор от Visual Studio тот же код скомпилировал в 2.5kb. Очень обидно, что с помощью любимого компилятора не удалось достичь тех же результатов
+1
Попробуйте подрезать «лишние» секции. Например:
strip FILENAME -R .comment
+1
Из секций и так остались только .text и .idata. Их в одну слить не получилось
SECTIONS
{
.text ALIGN(16): {
*(.text)
*(.rdata)
*(SORT(.rdata$*))
}
}
0
.text у кого меньше?
попробовать -Os; -fjump-tables и -fno-jump-tables; -fif-conversion -fif-conversion2;
в зависимости от версии GCC можно попробовать поработать с планировщиком и распределителем регистров.
попробовать -Os; -fjump-tables и -fno-jump-tables; -fif-conversion -fif-conversion2;
в зависимости от версии GCC можно попробовать поработать с планировщиком и распределителем регистров.
0
У EXEшника от Visual Studio только одна секция — .data.
Манипуляции с jump-tables и if-conversion не помогли.
GCC у меня 4.7.1:
Манипуляции с jump-tables и if-conversion не помогли.
GCC у меня 4.7.1:
Скрытый текст
c:\Program Files (x86)\CodeBlocks\MinGW\bin>gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/program files (x86)/codeblocks/mingw/bin/../libexec/gcc/mingw32/4.7.1/lto-wra
pper.exe
Target: mingw32
Configured with: ../../src/gcc-4.7.1/configure --build=mingw32 --enable-languages=c,c++,ada,fortran,
objc,obj-c++ --enable-threads=win32 --enable-libgomp --enable-lto --enable-fully-dynamic-string --en
able-libstdcxx-debug --enable-version-specific-runtime-libs --with-gnu-ld --disable-nls --disable-wi
n32-registry --disable-symvers --disable-build-poststage1-with-cxx --disable-werror --prefix=/mingw3
2tdm --with-local-prefix=/mingw32tdm --enable-cxx-flags='-fno-function-sections -fno-data-sections'
--with-pkgversion=tdm-1 --enable-sjlj-exceptions --with-bugurl=http://tdm-gcc.tdragon.net/bugs
Thread model: win32
gcc version 4.7.1 (tdm-1)
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/program files (x86)/codeblocks/mingw/bin/../libexec/gcc/mingw32/4.7.1/lto-wra
pper.exe
Target: mingw32
Configured with: ../../src/gcc-4.7.1/configure --build=mingw32 --enable-languages=c,c++,ada,fortran,
objc,obj-c++ --enable-threads=win32 --enable-libgomp --enable-lto --enable-fully-dynamic-string --en
able-libstdcxx-debug --enable-version-specific-runtime-libs --with-gnu-ld --disable-nls --disable-wi
n32-registry --disable-symvers --disable-build-poststage1-with-cxx --disable-werror --prefix=/mingw3
2tdm --with-local-prefix=/mingw32tdm --enable-cxx-flags='-fno-function-sections -fno-data-sections'
--with-pkgversion=tdm-1 --enable-sjlj-exceptions --with-bugurl=http://tdm-gcc.tdragon.net/bugs
Thread model: win32
gcc version 4.7.1 (tdm-1)
0
К сожалению, нет под рукой GCC под Windows. Подскажите опции при которых секция .text была минимальна (принимая в расчет только оптимизации самого .text). Посмотрю в каком месте GCC можно подкрутить.
0
Лучший случай:
Скрытый текст
Если добавить следующие опции, то размер секции .text не меняется.-s -O1 -Os
-nodefaultlibs
-nostartfiles
-mconsole
-lkernel32
-luser32
-lgcc
-Wl,ld_script_merge_rdata_and_text.x
.text
Physical Address 2024 $7E8 %11111101000
Virtual Address 4096 $1000 %1000000000000
Size of Raw Data 2048 $800 %100000000000
Pointer To Raw Data 512 $200 %1000000000
Pointer To Relocations 0 $0 %0
Pointer To Linenumbers 0 $0 %0
Number Of Relocations 0 $0 %0
Number Of Linenumbers 0 $0 %0
Characteristics 1613758560 $60300060 %1100000001100000000000001100000
-nodefaultlibs
-nostartfiles
-mconsole
-lkernel32
-luser32
-lgcc
-Wl,ld_script_merge_rdata_and_text.x
.text
Physical Address 2024 $7E8 %11111101000
Virtual Address 4096 $1000 %1000000000000
Size of Raw Data 2048 $800 %100000000000
Pointer To Raw Data 512 $200 %1000000000
Pointer To Relocations 0 $0 %0
Pointer To Linenumbers 0 $0 %0
Number Of Relocations 0 $0 %0
Number Of Linenumbers 0 $0 %0
Characteristics 1613758560 $60300060 %1100000001100000000000001100000
Скрытый текст
Если -O1 заменить на -O3, то получим:-ffunction-sections -Wl,--gc-sections
-fno-asynchronous-unwind-tables -Wl,--strip-all
-fvisibility=hidden -fvisibility-inlines-hidden
-fno-jump-tables
-fif-conversion2
-fno-asynchronous-unwind-tables
-fno-asynchronous-unwind-tables -Wl,--strip-all
-fvisibility=hidden -fvisibility-inlines-hidden
-fno-jump-tables
-fif-conversion2
-fno-asynchronous-unwind-tables
Скрытый текст
Если убрать скрипт линкера, то секция .text вообще не появляется.text
Physical Address 2196 $894 %100010010100
Virtual Address 4096 $1000 %1000000000000
Size of Raw Data 2560 $A00 %101000000000
Pointer To Raw Data 512 $200 %1000000000
Pointer To Relocations 0 $0 %0
Pointer To Linenumbers 0 $0 %0
Number Of Relocations 0 $0 %0
Number Of Linenumbers 0 $0 %0
Characteristics 1613758560 $60300060 %1100000001100000000000001100000
Physical Address 2196 $894 %100010010100
Virtual Address 4096 $1000 %1000000000000
Size of Raw Data 2560 $A00 %101000000000
Pointer To Raw Data 512 $200 %1000000000
Pointer To Relocations 0 $0 %0
Pointer To Linenumbers 0 $0 %0
Number Of Relocations 0 $0 %0
Number Of Linenumbers 0 $0 %0
Characteristics 1613758560 $60300060 %1100000001100000000000001100000
0
Демосцена 4k? :)
0
Демосцена — тру! Надеюсь, когда-нибудь смогу поучаствовать. А сейчас так, тренируюсь. Вопрос заинтересовал в принципиальном плане, вот и ковырялся
0
Ну если ориентироваться только на винду и маленькие файлы, то почему бы не попробовать кринклер? www.crinkler.net/
0
Иногда возможные оптимизации скрываются там, где их не ждешь.
GCC по умолчанию делает все функции экспортируемыми из динамической библиотеки. Недавно получилось уменьшить размер библиотеки на 24% (с 16.6 до 12.6 Mb) за счет опций "-fvisibility=hidden -fvisibility-inlines-hidden"
GCC по умолчанию делает все функции экспортируемыми из динамической библиотеки. Недавно получилось уменьшить размер библиотеки на 24% (с 16.6 до 12.6 Mb) за счет опций "-fvisibility=hidden -fvisibility-inlines-hidden"
+3
Почему нет варианта
-Os -flto
?0
Прежде всего, котаны, надо писать хороший код — не злоупотреблять шаблонами в крестах и т.п.
Далее, выигрыш от конкретных опций gcc зависит от приложения, стиля кода, модной в этом сезоне версии gcc и фазы луны. Поэтому надо брать GC Masher, который автоматически грубой силой переберет все возможные параметры gcc с целью нахождения глобального минимума.
Ну и напоследок можно попробовать сжать бинарник каким-нибудь exe-пакером, типа UPX, или вовсе на коленке соорудить gzip-дроппинг.
В этом месте можно убедиться, что все предыдущие оптимизации размера сказываются на размере сжатого файла не монотонно, и, господи, зачем вообще я пишу этот комментарий.
Далее, выигрыш от конкретных опций gcc зависит от приложения, стиля кода, модной в этом сезоне версии gcc и фазы луны. Поэтому надо брать GC Masher, который автоматически грубой силой переберет все возможные параметры gcc с целью нахождения глобального минимума.
Ну и напоследок можно попробовать сжать бинарник каким-нибудь exe-пакером, типа UPX, или вовсе на коленке соорудить gzip-дроппинг.
В этом месте можно убедиться, что все предыдущие оптимизации размера сказываются на размере сжатого файла не монотонно, и, господи, зачем вообще я пишу этот комментарий.
+4
«хороший код» реально писать, если пишешь его в одиночку и с нуля. Зачастую некоторые интерфейсы уже написаны.
Грубая сила предполагает высокую скорость компиляции или наличие крутого сервера.
Что-то мне подсказывает, что 90% эффекта от «грубой силы» можно добиться «здравым смыслом».
Про архивацию — правда, но уже не про GCC/LD.
Грубая сила предполагает высокую скорость компиляции или наличие крутого сервера.
Что-то мне подсказывает, что 90% эффекта от «грубой силы» можно добиться «здравым смыслом».
Про архивацию — правда, но уже не про GCC/LD.
0
На неконтролируемом входном коде можно вообще схватить подчеркнутое той или иной опцией неопределенное поведение в стандарте языка.
Да, здравый смысл конечно 90% покрывает, а грубая сила нужна только для случаев «о боже, я вылез на 35 байт за пределы дозволенного!», да и вообще предполагает прежде всего крохотулечные проекты, потому что никаких серверов не хватит хромиум перебирать.
Кстати, -mfpmath=sse не круто с точки зрения размера — там водятся толстенные 7-байтные инструкции, тогда как олдовые fpu'шные укладываются в 2.
Да, здравый смысл конечно 90% покрывает, а грубая сила нужна только для случаев «о боже, я вылез на 35 байт за пределы дозволенного!», да и вообще предполагает прежде всего крохотулечные проекты, потому что никаких серверов не хватит хромиум перебирать.
Кстати, -mfpmath=sse не круто с точки зрения размера — там водятся толстенные 7-байтные инструкции, тогда как олдовые fpu'шные укладываются в 2.
+1
Зато по скорости исполнения выигрывают. Это тоже немаловажный фактор.
0
Кстати, -mfpmath=sse не круто с точки зрения размера
Согласен. Особенно если использовать встроеный sin, например. Правда, и вещественная арифметика почти не представлена в тех приложения, что были использованны для получения цифр (для мобилных приложений более свойственны целочисленные вычисления, вещественные завернуты в библиотеки).
0
С sin вообще забавно получается — если не выпендриваться, gcc на место sin (когда я в последний раз смотрел году в 2009) вместо того, чтобы православно заинлайнить fsin, генерирует вызов в libm, который там у себя внутри считает синус самостоятельно (емнип, оно даже в этот самый fsin не упирается в итоге, но не буду утверждать).
0
Код написан. Старался писать так, чтоб результирующий файл имел минимальный размер. GCC генерирует результирующий код размером 3kb, Visual Studio — 2.5kb (подробности выше). Стандартный набор опций GC Masher'a уменьшить размер не помог — всё так же 3kb. По-моему, цель данной статьи скорее помочь найти нужные ключи GCC, которые помогут уменьшить размер… И да, при таком размере UPX не ужал ни на байт.
0
Очень интересно, ждем про x86_64!
0
Размер важен для демосцены, там — да, наслаждаешься безумством «упертых»
Скорость важна для технологических применений (встраиваемые решения, рендеринг и т.п.)
Гораздо важнее КАЧЕСТВО кода. Вымораживает, когда современный софт срыгивает чем-нибудь вроде:
«не могу открыть файл.»
КАКОЙ, блджад, файл ты не можешь открыть, чудо ты корпоративное! Неужели трудно в исходниках прописать конкретно ошибку, сэкономив персоналу ЧАСЫ времени на поиски неисправности…
Скорость важна для технологических применений (встраиваемые решения, рендеринг и т.п.)
Гораздо важнее КАЧЕСТВО кода. Вымораживает, когда современный софт срыгивает чем-нибудь вроде:
«не могу открыть файл.»
КАКОЙ, блджад, файл ты не можешь открыть, чудо ты корпоративное! Неужели трудно в исходниках прописать конкретно ошибку, сэкономив персоналу ЧАСЫ времени на поиски неисправности…
0
Sign up to leave a comment.
GCC x86, как уменьшить размер кода