对于来自http://bellard.org/mersenne.html的程序,GCC产生~130MB的可执行文件。为什么呢?
答案 0 :(得分:12)
尝试将t[1<<25]={2}
更改为t[1<<25]
,*可执行文件**的大小将下拉至 7.3 K 。 (不用说,你不会得到正确的结果)
如果它只是t[1<<25]
,它就不会占用任何空间。
这里的问题是数组正在被初始化(第一个元素= 2,接下来的2 ^ 25-1个元素全部为0),全局数组被放置在仅的数据段中,因为它被初始化了。
<小时/> 生成2个版本的程序集并检查其差异使其更加清晰:
[axiom@axiom ~]$ diff without_mem.s with_mem.s
15c15,21
< .comm t,134217728,32
---
> .globl t
> .align 32
> .type t, @object
> .size t, 134217728
> t: ***<- HERE!***
> .long 2
> .zero 134217724
我们可以注意到,在原始版本中,汇编器被指示在数据段中生成2 ^ 27(134217728)个字节。所以它成为目标文件本身的一部分。 (您可以通过使用-S
开关gcc -S -fverbose-asm t1.c
进行编译来生成程序集
1<< n= 2^n (1 left shifted n times). => 1<<25=2^25. now 1 Integer= 4 bytes =2^2 bytes => 2^25 Integers=2^27 bytes=2^7 * 1 M bytes= 128 MBs
<小时/> *注1:严格来说是object file。
注2:正如评论中所指出的,还可以注意到,即使可执行文件是7.3K,进程(执行中的程序)的总大小也将是129Mb。 (程序开始执行后将分配内存)。您可以使用top
命令查看程序的内存使用情况。
注3:值得强调的是,这只是因为t是全局的。函数本地数据的分配仍然在堆栈上的运行时发生。因此,如果t
是本地的,则目标文件仅占用7.3K。
注4:初始化的static
局部变量(如初始化的全局变量)也保留在data
段中。除了您将变量的范围仅限制为当前文件外,static
全局与相同。