如何减少生成的二进制文件的大小? [英] How to decrease the size of generated binaries?

查看:145
本文介绍了如何减少生成的二进制文件的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有一个选项-Os来优化大小,​​但是它影响不大,甚至在某些场合增加了大小:(



< (或-s选项)删除调试符号表,这工作正常,但它只能减少一个小的比例尺。



任何其他方式去furthur?

解决方案

除了显而易见( -Os -s ),将函数对齐到不会崩溃的最小可能值(我不知道ARM对齐要求)可能会挤出每个函数几个字节。

- Os should 已经禁用了对齐函数,但是这可能仍然默认为一个像4或8这样的值。如果使用ARM对齐例如1,那可能会节省一些字节。

-ffast-math (或者磨蚀性较小 -fno-math-errno )不会设置errno并避免一些检查,这会减少代码的大小。如果像大多数人一样,你不会重新无论如何,这是一个选项。



正确使用 __ restrict (或 restrict code>)和 const 删除多余的负载,使代码更快更小(更正确)。正确标记纯函数可以调用函数调用。



启用LTO可能会有所帮助,如果不可用,则一次性将所有源文件编译为二进制文件( gcc foo.c bar.c baz.c -o program 而不是编译 foo.c bar.c baz.c 首先映射到目标文件,然后连接)将产生类似的效果。它使优化器中的所有内容一次都可见,可能会让它工作得更好。



-fdelete-null-pointer-checks 可能是一个选项(请注意,这通常对任何O启用,但嵌入式目标上的 not )。

把静态的全局变量(你希望没有那么多,但仍然)放入一个结构体中可以消除很多开销来初始化它们。我了解到,在编写我的第一个OpenGL加载器时。让所有函数指针在一个结构体中,并使用 = {} 初始化结构体将产生一次对 memset 的调用,而初始化指向正常方式的代码会生成一个百千字节的代码,将每个代码单独设置为零。



避免使用非平凡构造函数static local em>像魔鬼这样的变量(POD类型没有问题)。除非你使用 -fno-threadsafe-statics 编译,否则Gcc会初始化非平凡构造函数的静态局部线程安全,这会在很多的额外代码中链接(即使你根本不使用线程)。



使用类似libowfat而不是普通的crt可以大大减少你的二进制大小。


I know that there is an option "-Os" to "Optimize for size", but it has little affect, or even increase the size on some occasion :(

strip (or "-s" option) removes debug symbol table, which works fine; but it can only decrease only a small propotion of the size.

Is there any other way to go furthur?

解决方案

Apart from the obvious (-Os -s), aligning functions to the smallest possible value that will not crash (I don't know ARM alignment requirements) might squeeze out a few bytes per function.
-Os should already disable aligning functions, but this might still default to a value like 4 or 8. If aligning e.g. to 1 is possible with ARM, that might save some bytes.

-ffast-math (or the less abrasive -fno-math-errno) will not set errno and avoid some checks, which reduces code size. If, like most people, you don't read errno anyway, that's an option.

Properly using __restrict (or restrict) and const removes redundant loads, making code both faster and smaller (and more correct). Properly marking pure functions as such eleminates function calls.

Enabling LTO may help, and if that is not available, compiling all source files into a binary in one go (gcc foo.c bar.c baz.c -o program instead of compiling foo.c, bar.c, and baz.c to object files first and then linking) will have a similar effect. It makes everything visible to the optimizer at one time, possibly allowing it to work better.

-fdelete-null-pointer-checks may be an option (note that this is normally enabled with any "O", but not on embedded targets).

Putting static globals (you hopefully don't have that many, but still) into a struct can eleminate a lot of overhead initializing them. I learned that when writing my first OpenGL loader. Having all the function pointers in a struct and initializing the struct with = {} generates one call to memset, whereas initializing the pointers the "normal way" generates a hundred kilobytes of code just to set each one to zero individually.

Avoid non-trivial-constructor static local variables like the devil (POD types are no problem). Gcc will initialize non-trivial-constructor static locals threadsafe unless you compile with -fno-threadsafe-statics, which links in a lot of extra code (even if you don't use threads at all).

Using something like libowfat instead of the normal crt can greatly reduce your binary size.

这篇关于如何减少生成的二进制文件的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆