2012-12-06 65 views
2

我在我的主机(linux x86)和目标机器(arm)上运行的C++中编写了一个小应用程序。
我的问题是,在主机上我的二进制文件大小约为700kb,但在目标机器上它大约为7mb。
我在两个平台上都使用相同的编译开关。我的第一次是,arget机器上的一个库被静态链接了,但我用objdump检查了这两个二进制文件,两者都使用相同的动态链接库。 所以任何人都可以给我提示,我怎么能找出为什么有这么大的差异?交叉编译时的文件差异

+2

这是什么应用程序?你究竟如何编译和链接它?什么版本的编译器,链接器....给我们更多的细节.... –

+1

你检查了静态与动态链接? –

+2

剥离与未剥离的二进制文件有什么关系?如果ARM二进制文件仍然有它的调试符号,它将会大得多。你可以尝试剥离两个二进制文件,看看会发生什么...... – thkala

回答

2

虽然不同的计算机体系结构可以从理论上需要完全不同数量的可执行代码用于同一个程序,但在现代体系结构中并不真正期望10的因子。 ARM和x86可能会有所不同,但它们仍然设计在同一个宇宙内存和带宽不可浪费的地方,这导致CPU设计人员尽力保持可执行代码尽可能的紧凑。

我,所以,看看下面的可能性,以概率:

  • 符号剥离:如果两个二进制文件之一已经从它的符号剥离,那么这将是显著更小,尤其是如果使用调试信息进行编译你可能想试图去掉两个二进制文件,看看会发生什么。

  • 静态链接:我偶尔会遇到用于嵌入式目标的构建系统,它们宁愿使用静态链接来使用共享库。检查每个二进制文件的库依赖关系可能会检测到这一点。

  • 其他启用的代码:较大的二进制文件可能会启用其他代码,例如,构建系统找到了一个附加的可选库,或者因为目标平台需要特定的处理。

    尽管如此,10的因子可能太多了,除非较小的二进制文件缺少很多功能,或者较大的一个静态地链接到某些可选库中。

  • 不同的编译器配置:你不应该只看编译器选项你提供的,而且编译器使用的默认值是每个目标。例如,如果编译器在一个体系结构中具有显着更高的内联或展开循环展开限制,则可执行结果可能会明显变差。

+0

我应该想到自己剥离。我没有弄清楚我的构建有什么区别,但是目前我的可执行文件的后期剥离就足够了。感谢提示。 – mkaes

1

首先没有理由期望为不同体系结构编译的相同代码在大小上有任何种类的关系。你可以很容易地让A比B大,然后改变一行代码,然后B比A大。

其次,你所说的“二进制文件”是我猜小精灵,这是一个二进制和一些开销很大。架构和其他此类事物之间的开销可能有所不同。

如果您针对两种体系结构/平台编译相同的代码,或者针对相同体系结构使用不同的编译器或编译选项,则没有理由期望文件大小彼此具有任何关系。

+1

同意,但我希望在x86和ARM之间至多有2倍。 10的因素似乎对不同的汇编/临时选项有所怀疑 –

0

不同的体系结构可以有完全不同的方式来处理同样的事情。例如,在CISC(例如x86)架构上加载立即值通常是一条指令,而在RISC(例如ppc,arm)上它通常是多于一条指令,所需的实际数目取决于该值。例如,如果指令集只允许16位立即值,则最多可能需要7条指令来加载64位值(加载16位并在两个加载之间切换)。因此,代码本质上是不同的。

0

到目前为止尚未提及但与ARM/x86比较相关的一个原因是浮点仿真。目前所有的x86芯片都具有本地FP支持(即使通过SSE支持SIMD FP也支持x86-64),但ARM CPU通常缺少FP单元。这反过来意味着即使是简单的FP加法也必须转化为指数和尾数的整数运算的长序列。