Аннотация :
Статья посвящена вопросам оптимизации размера выполняемых модулей, генерируемых различными
компиляторами C++ (основное внимание уделено MS Visual С++). С этой целью рассматриваются особенности Библиотеки исполнения C/C++ и ее реализаций, а также процессы компиляции и компоновки приложений. Приведены практические приемы, позволяющие в ряде случаев уменьшить размер приложения до величины 3-4 килобайта.
Успехов,
Виталий.
Re: Но не забудьте, что такой файл будет медленнее
Эта оптимизация (/opt:win98) позволяет существенно более эффективно кэшировать исполняемые файлы ущербному менеджеру виртуальной памяти в Win98. Эффект сказывается не на первой загрузке, а на последующих, или, в случае DLL, когда много процессов используют одну и ту же DLL.
Все разговоры про NT и NTFS совершенно бессмысленны, так как при выполнении на NT эта опция не имеет никакого значения.
-- Alex Fedotov
Re[4]: Анатомия C Run-Time, или Как сделать программу немног
Здравствуйте, Ash-2, Вы писали:
__>>Да можно, в опциях выбрать /MD и выбрать entrypoint : main. A2>Насколько я понял это не выход. A2>Конечно, надо попробовать и посмотреть, что сотворит VC, но из поста напрашивается лишь один вывод: я просто меняю имя функции "пользовательского входа в программу". Иными словами используется та же crt, но вызывает она не WinMain и main (на ее место м.б. любая функция)...
Нет, опция /entry линкера задает имя функции — реальной стартовой точки. По умолчанию она указывает на функцию инициализации CRT (xxxCRTStartup), соответственно, указывая в этой опции main, получаем вызов main без CRT.
Но этот способ не из лучших: глобальные конструкторы мне слишком дороги.
Успехов,
Виталий.
Re[2]: Анатомия C Run-Time, или Как сделать программу немног
Здравствуйте, Ash-2, Вы писали:
A2>1. Можно ли использовать IDE VC++ 7.1 для варианта "без CRT"? A2>Насколько я понял vc честно предлагает выбрать "тип" crt, но отказаться от него нельзя...
Можно, например, для ATL это выполняется линковкой с библиотекой atlmincrt.lib.
Другой вариант — использовать библиотеку Мэтта Питрека (включить в проект один файл mincrt.cpp).
Я еще уменьшал размер полученного EXE, отключая так называемую security check: проверку переполнения буфера.
Алекс Федотов предлагал недавно свой вариант, мой достигается включением в проект такого файла:
A2>2. Опять "вариант без CRT": а что я теряю в плане вычислений с плавающей точкой?
Да ничего, практически. Эмуляция в современных процессорах не нужна, а большинство функций (sin, cos) доступны в inline-варианте (/Oi).
A2>И что делает компилятор для "устранения ошибки процессора (intel) в операциях с плавающей точкой"?
Не в курсе. Видимо, вместо DIV генерирует в некоторых случаях серию других инструкций. Вероятность попадания на такой процессор ничтожна — лично я пишу софт не для спутников.
-> Но не забудьте, что такой файл будет медленнее загружаться в память...
Да, 3 кб будет медленее загружаться чем 33 — железная логика (MS)! Я долго смеялся ...
Ну, из 30-килобайтного файла 3-килобайт опцией /opt:nowin98 не получишь. Для статического рантайма выигрыш всего-то около 7 килобайт. Чем больше размер EXE, тем меньше относительный выигрыш (и тем большую цену мы платим за размер, проигрывая в скорости загрузки).
Вот такой вот код, включающий выделение памяти из кучи,
строки неог. длины, преобразование строки в целое, вещественного в целое, чтение и запись в файл аналогами printf и
scanf дает при компиляции 15 872 b.
program project1;
uses
Windows;
var s: string;
pi: ^integer;
F: Text;
d: double;
c: integer;
begin
Assign (F, 'c:\a.txt');
Reset (F);
readln (F, s);
readln (F, d);
new (pi);
val (s, pi^, c);
if pi^ > d then
MessageBox (0, '>', '', MB_OK)
else
MessageBox (0, '<=', '', MB_OK);
close (F);
ReWrite (F);
writeln (F, d);
writeln (F, pi^);
close (F);
dispose (pi);
end.
Если, например, юзать LIBCTINY.LIB от Питрека, такая программа на C++ и за 4 Кб не зашкалит (лень пример приводить, но у меня микроинсталлятор с распаковкой файлов и выполнением JScript-сценариев 12 Кб, сжатый — 8 Кб).
Успехов,
Виталий.
Re: Но не забудьте, что такой файл будет медленнее
Не железная, а титановая с вольфрамовым армированием. Причем, совершенно справедливая.
Дело в том что операционке (точнее ее дисковой подсистеме) проше и быстрее читать данные с гранулярностью в кластер (те же 4 кила). И это будет справедливо для любой файловой системы и для любой операционки.
А приятно что что один отдел большого мелкософта (компиляторщики) нашел общий язык с другим отделом (операционщиками)...
____________________
God obviously didn't debug, hasn't done any maintenance, and no documentation can be found. Truly amateur work.
Получается, что в ядре есть аналоги ко многим функциям CRT. В KB даже есть статья "Win32 Equivalents for C Run-Time Functions" (Article ID: Q99456).
Но если я не могу обойтись без разбора строки функцией sscanf? Получается, что из-за одной функции мне придется использовать CRT? Или извращаться ручками из строки вытаскивать разного типа переменные... вот такой from gates...
А чем VariantChangeType не устраивает (для преобразования из строки в число)?
А парсить строку по формату — не такая уж тривиальная операция. За ее наличие "нахаляву" не жалко и 30 Кб заплатить...
Успехов,
Виталий.
Re: Но не забудьте, что такой файл будет медленнее
Не-аа. Не для любой. Тот же NTFS первые 2 кила хранит прямо в своих структурах, которые обычно в памяти кешируются, а за второй половиной лезет в удаленные кластеры. CDFS вообще все потоком хранит. Так что хреновая это экономия. Да и экономить, там практически нечего. Скорость считывания с диска на два порядка ниже, и эту оптимизацию пропросту не видно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
>> Но встречаются случаи, когда считаешь буквально каждый байт исполняемого модуля. Это может >> быть ядро инсталлятора или самораспаковывающегося архива....
Господа, а про ASM вы случайно не зыбыли ?
В случае, если требуется действительно минимальный объем EXE, единственный выход — ASM.
Незачем кастрировать C++ для того, что можно сделать на ассемблере без усилий :)
P.S. А если в PE сделать всего 1 секцию, то и выравнивание значения не имеет :)
У каждого, как известно, свое мнение о предпочтительном инструменте для каждой конкретной задачи. Но тот факт, что С и C++ являются признанными лидерами системного программирования, я думаю, очевиден.
PS: И, как обычно, оптимизировав модуль на C++, можно "довести" его, использовав сгенерированный листинг ASM...
До прочтения статьи, я незнал про секретную опцию (/opt:nowin98) поэтому пришлось найти меене секретную (/ALIGN).
и того #pragma comment(linker, "/ALIGN:0x1000 0x200") дает в принципе тотже результат имхо...
А, да, про лишнее то чуть незабыл =)
В ехешнике между dos-stub и PE заголовком есть какаято абра кадабра которую имхо не кто не юзает (я точно), так вот как от нее избавиться то?
Здравствуйте, VladD2, Вы писали:
VD>А ты с Дельфевыми 300 кило сравни...
D>Очевидно, сравнивать библиотеки классов с инициализационным рантаймом — не есть гуд.
VD>А ты можешь их отделить?
Разумеется могу. Не использовать vcl. Рантайм дельфей — килобайт 15-ть.
Re: Анатомия C Run-Time, или Как сделать программу немного м
Здравствуйте, Виталий Брусенцев, Вы писали:
ВБ>Статья :
ВБ>Авторы : ВБ>Виталий Брусенцев
ВБ>Аннотация : ВБ>Статья посвящена вопросам оптимизации размера выполняемых модулей, генерируемых различными ВБ>компиляторами C++ (основное внимание уделено MS Visual С++). С этой целью рассматриваются особенности Библиотеки исполнения C/C++ и ее реализаций, а также процессы компиляции и компоновки приложений. Приведены практические приемы, позволяющие в ряде случаев уменьшить размер приложения до величины 3-4 килобайта.
Вопросов два (Win2k и выше):
1. Можно ли использовать IDE VC++ 7.1 для варианта "без CRT"?
Насколько я понял vc честно предлагает выбрать "тип" crt, но отказаться от него нельзя...
2. Опять "вариант без CRT": а что я теряю в плане вычислений с плавающей точкой? И что делает компилятор для "устранения ошибки процессора (intel) в операциях с плавающей точкой"?
P.S. Поскольку crt используется не очень активно есть соблаз отказаться от нее, поэтому и вопросы...
Re[2]: Анатомия C Run-Time, или Как сделать программу немног
Здравствуйте, Ash-2, Вы писали:
A2>Здравствуйте, Виталий Брусенцев, Вы писали:
A2>Статья очень хорошая.
A2>Вопросов два (Win2k и выше): A2>1. Можно ли использовать IDE VC++ 7.1 для варианта "без CRT"?
В VC 7.1 можно тоже отказаться от CRT A2>Насколько я понял vc честно предлагает выбрать "тип" crt, но отказаться от него нельзя...
Да можно, в опциях выбрать /MD и выбрать entrypoint : main. A2>2. Опять "вариант без CRT": а что я теряю в плане вычислений с плавающей точкой? И что делает компилятор для "устранения ошибки процессора (intel) в операциях с плавающей точкой"?
A2>P.S. Поскольку crt используется не очень активно есть соблаз отказаться от нее, поэтому и вопросы...
Можно попробовать использовать _ATL_MIN_CRT тогда будет приемлимая функциональность и не будет большой размер, но если размер критичен и есть желание реализовать выделение памяти и инициализацию глобальных объектов руками то можно отказаться от CRT.
Примечание: если в программе используется STL, то в VC 7.1 от CRT отказаться нельзя.
Здравствуйте, _nn_, Вы писали:
__>Можно попробовать использовать _ATL_MIN_CRT тогда будет приемлимая функциональность и не будет большой размер, но если размер критичен и есть желание реализовать выделение памяти и инициализацию глобальных объектов руками то можно отказаться от CRT.
Используйте mincrt.lib от Питрека и будет щастье
__>Примечание: если в программе используется STL, то в VC 7.1 от CRT отказаться нельзя.
Да, со стандартной библиотекой у меня это не получилось, а вот STLPort отучить от CRT можно.
Успехов,
Виталий.
Re[4]: Анатомия C Run-Time, или Как сделать программу немног
Здравствуйте, _nn_, Вы писали:
A2>>1. Можно ли использовать IDE VC++ 7.1 для варианта "без CRT"? __>В VC 7.1 можно тоже отказаться от CRT A2>>Насколько я понял vc честно предлагает выбрать "тип" crt, но отказаться от него нельзя... __>Да можно, в опциях выбрать /MD и выбрать entrypoint : main.
Насколько я понял это не выход.
Конечно, надо попробовать и посмотреть, что сотворит VC, но из поста напрашивается лишь один вывод: я просто меняю имя функции "пользовательского входа в программу". Иными словами используется та же crt, но вызывает она не WinMain и main (на ее место м.б. любая функция)...
Сорри, 8 студию пока еще руками не трогал. Видимо, там многое поменялось в части CRT.
Успехов,
Виталий.
Re[4]: libc.lib в 8-ой студии
От:
Аноним
Дата:
08.08.05 07:24
Оценка:
Здравствуйте, retalik, Вы писали:
R>Здравствуйте, Аноним, Вы писали:
А>>И это А>>
А>>extern"C"int _fltused = 0;
А>>
А>>почему то не устраивает?
Ставим
Visual C++ Compiler Options
/fp:[precise | except[-] | fast | strict ]
в
fast
Creates the fastest code in the majority of cases. /fp:fast cannot be used with /fp:strict or /fp:precise, the last option specified on the command line will be used. /fp:fast and /fp:except will generate a compiler error. Selecting /Za (ANSI compatibility) and /fp:fast may result in unexpected behavior. For example, single-precision floating-point operations may not be rounded to single precision.
except[-]
Эту абракадабру вставляет туда M$-овский линкер (сигнатура Rich).
В ней покриптованы некоторые аппаратные ID-шники компа
на котором exe-шник компилили.
Для чего это нужно не знаю. Толи чтоб автора было легче найти, толи так, для развлекухи.
Впрочем енто легко лечится. В нете валяются патчи на link.exe
После применения которых, там остаются только приятные глазу нули.
Re[5]: Анатомия C Run-Time, или Как сделать программу немног
[skipped]
R>Но этот способ не из лучших: глобальные конструкторы мне слишком дороги.
Ну и зря, статическая инициализация работает прекрасно, а глобальные конструкторы
изпользовать не рекомендуют, тк стандартом не определен порядок их вызова.
Singleton рулит!
Здравствуйте, unreg_flex, Вы писали:
_>В ней покриптованы некоторые аппаратные ID-шники компа
Вот здесь разбирали сабж. Утиль _>Впрочем енто легко лечится. В нете валяются патчи на link.exe _>После применения которых, там остаются только приятные глазу нули.
Или вообще ничего не остаётся