• Welcome to Dark Bit Factory & Gravity.
 

Visual c++ code optimization.

Started by Blacksheep8Bit, March 21, 2012

Previous topic - Next topic

0 Members and 0 Guests are viewing this topic.

Blacksheep8Bit

So i was wondering what are the best configurations for a visual c++ 2010 project in order to make a small exe, since we are talking about demos i thought that i would need special kinds of configurations.

I Already tried KKRUNCHY but i think i can make it even smaller by configuring visual c++ and even more smaller using KKRUNCHY after. I Am currently using the standard release settings.
Challenge Trophies Won:

LittleWhite

Hello,

Someone gave me this link -> http://www.catch22.net/tuts/minexe a long time ago ... I hope the article is still in place :s
I guess it is this one -> http://www.catch22.net/tuts/reducing-executable-size
The demoscene will never die, never!

Knurz

Hi!

Have a look at this page: http://wiki.wxwidgets.org/Reducing_Executable_Size there are some nice flags documentated which should reduce the Exe Size.

I tried to build a tiny executable with VS2010 but I didn't really came close to a striped GCC's executable.

KKRUNCHY is nice but has some limits. I used the beroexepacker which performed really nice (decrunching is much faster) and seems to be worked on till now: http://bero.0ok.de/blog/projects/beroexepacker/

If you do C Code you can try CodeBlock - which is a very nice IDE, and MinGW GCC for compiling (I'm from Unix-World, so a Windowsuser maybe confused by the options/MAKEFILE). After linking you can use the "strip" commando to build a really tiny executable, and crunch this with the Beroexepacker.

cu.
Remember what the dormouse said: Feed your head

longwang

Hi!

I like to use UPX:
http://upx.sourceforge.net/

Makes the executables really small. Since I never tried another tool I can't tell which packer performs best. I guess you have to try them...
hc

Jim

crinkler is pretty good - it replaces the VC linker.  Has some limitation when used with C++ and likes to start with small exes.
Jim
Challenge Trophies Won:

rain_storm

#5
This is geared towards MSVC 2008 but it should be compatible.

[1] create an empty Win32 Console Application.
[2] Then set the Configuration to "Release"
[3] Now add a new cpp file to the project (Project -> Add New Item) named tiny.cpp
[4] Paste the following into tiny.cpp

#include <windows.h>
int main(void)
{
MessageBoxA(0, "Hello World!", 0, 0);
return 0;
}

[5] Build the solution (Build -> Build Solution) and you should get a 7KB executable.
[6] Open the Project Settings DialogBox (Project -> Properties) and apply the
following settings:

Configuration Properties - General - Character Set - Not Set
Configuration Properties - Manifest Tool - Input and Output - Embed Manifest - No
Configuration Properties - Build Events - Post Build Events - Command Line - cmd /c dir "$(TargetPath)"
Configuration Properties - C/C++ - General - Debug Information Format - Disabled
Configuration Properties - C/C++ - Optimization - Omit Frame Pointers - Yes
Configuration Properties - C/C++ - Optimization - Enable Fibre Safe Optimizations - Yes
Configuration Properties - C/C++ - Code Generation - Enable C++ Exceptions - No
Configuration Properties - C/C++ - Code Generation - Runtime Library - Multi Threaded DLL
Configuration Properties - C/C++ - Code Generation - Buffer Security Check - No
Configuration Properties - Linker - Input - Ignore Default Libraries - Yes
Configuration Properties - Linker - Manifest File - Generate Manifest - No
Configuration Properties - Linker - Debugging - Generate Debug Info - No
Configuration Properties - Linker - Advanced - Randomize Base Address - Default
Configuration Properties - Linker - Advanced - Data Execution Prevention - Default


[7] Replace the contents of tiny.cpp with the following:

#include <windows.h>
void mainCRTStartup(void)
{
MessageBoxA(0, "Hello World!", 0, 0);
return;
}

[8] Rebuild the solution (Build -> Rebuild Solution) and you should get a 2KB program.
[9] Back in the Project Settings DialogBox (Project -> Properties) add the following
command line arguments to the linker:

Configuration Properties - Linker - Command Line - Additional Options -
/ALIGN:16
/filealign:16
/ignore:4108


[10] Rebuild the solution (Build -> Rebuild Solution) and you should get it down to 672 bytes.
[11] Return to the Project Settings (Project -> Properties) replace the previous
Command Line Arguments for the linker with this new and revised version:

Configuration Properties - Linker - Command Line - Additional Options -
/MERGE:.rdata=.data
/MERGE:.data=.text
/ignore:4254

/SECTION:.text,RWE
/ALIGN:16
/filealign:16
/ignore:4108


[12] After rebuilding (Build -> Rebuild Solution) you should be greeted with an executable thats only 608 bytes.

[13] Create a new file called stub.asm and paste the following into it:

format binary as 'exe'
mzhdr:                       ;
    .e_magic    dw "MZ"       ;
    .e_cblp     dw 0x0090     ;
    .e_cp       dw 0x0003     ;
    .e_crlc     dw 0x0000     ;
    .e_cparhdr  dw 0x0004     ;
    .e_minalloc dw 0x0000     ;
    .e_maxalloc dw 0xFFFF     ;
    .e_ss       dw 0x0000     ;
    .e_sp       dw 0x00B8     ;
    .e_csum     dw 0x00C3     ; .entry: ret
    .e_ip       dw 0x0012     ; @.entry
    .e_cs       dw 0x0000     ;
    .e_lsarlc   dw 0x0040     ;
    .e_ovno     dw 0x0000     ;
    .e_res      dw 4 dup ?    ;
    .e_oemid    dw 0x0000     ;
    .e_oeminfo  dw 0x0000     ;
    .e_res2     dw 10 dup ?   ;
    .e_lfanew   dd 0x00000000 ;

[14] Assemble stub.asm using FASM and you should see a file stub.exe thats 64 bytes.
[15] Back in Visual Studio's Project Settings (Project -> Properties) we're going to
over-ride the default stub with our own custom stub. Replace the existing linker
Command Line Arguments with the following:

Configuration Properties - Linker - Command Line - Additional Options -
/STUB:$(SolutionDir)stub.exe

/MERGE:.rdata=.data
/MERGE:.data=.text
/ignore:4254

/SECTION:.text,RWE
/ALIGN:16
/filealign:16
/ignore:4108


[16] Rebuild the Solution (Build -> Rebuild Solution) and you have 560 bytes.
[17] Then take the patched version of link.exe that I supply here and place it in your project directory and rebuild

480 bytes

any lower than that and you'll have to use an assembler.

But this is a lot of work for little reward. Best to just use a good compressor such as crinkler.

Edit : Va!n here's the same project you posted but got the size down to 944 bytes using the above settings.

Challenge Trophies Won:

Blacksheep8Bit

HOLY SHIT! RAIN_STORM ARE YOU A PROGRAMMING GOD?

THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS THANKS
Challenge Trophies Won:

rain_storm


Challenge Trophies Won:

Canopy


some great info in here.

VS is a bugger when you drag in the runtimes.


however, small is not necessarily faster.

for example one common optimisation is the act of unrolling loops to eliminate recursion.

are there any pointers on that kind of optimisation?

i dont care about exe size, i care more about raw speed.

rain_storm

Read Agner Fog's Optimization Manuals they are the de facto resource on the matter.

Challenge Trophies Won:

va!n

K++ @ rain_storm...
Btw, could you help to optimize a tiny Win32-Window project in its exe size - but without using crinkler nor using asm stub? (It compiles to 7680 bytes atm and is using MSVCR110.dll)

Many thanks in advance. Best regards...

- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Raizor

Excellent resource rain_storm, K++
raizor

Challenge Trophies Won:

hellfire

#12
Quote from: va!n on June 03, 2012
could you help to optimize a tiny Win32-Window project in its exe size - but without using crinkler nor using asm stub?
First of all disable manifest, unicode and debuginfos.
Enable "ignore all default libraries" and rename "WinMain(...)" to "WinMainCRTStartup()".
Get instance from
HINSTANCE hInstance= GetModuleHandle(0);
Should end up at about 2kb.


Challenge Trophies Won:

va!n

Thanks a lot. I have tried your tips but i get always two compiler errors:

Error   1   error LNK2001: Nicht aufgelöstes externes Symbol "@__security_check_cookie@4".   e:\SourceCodes\Tiny\winbase\main.obj   winbase
Error   2   error LNK1120: 1 nicht aufgelöste externe Verweise.   E:\SourceCodes\Tiny\Release\winbase.exe   winbase

Any idea what's wrong?
- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Rbz

Try do disable "Buffer Security Check".

Configuration Properties > C/C++ > Code Generation > Buffer Security Check = No


Challenge Trophies Won:

Blacksheep8Bit

I Guess if i want it smaller i will need to learn assembly...


I am downloading 500mb of assembly + winapi books  :D
Challenge Trophies Won:

va!n

@hellfire:
thanks! K++

@rbz:
thanks! K++

@Blacksheep8Bit:
I think with ASM the size in this case will not be smaller, because afaik the size is as follow:

1024 PE Header
512 Section text
512 Section rdata
512 Section reloc

Total: 2560 bytes

Maybe it would be possible to merge sections, so you could gain 512 or maybe up to 1024 bytes but i am not sure how compatible the exe is after this.
- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

jace_stknights

Pfew after reading this, I remember the good old time of 68k coding   :whack:
Challenge Trophies Won: