6

对于来自http://bellard.org/mersenne.html的程序, GCC 生成 ~130MB 可执行文件。为什么?

4

1 回答 1

12

尝试更改t[1<<25]={2}t[1<<25]*executable** 的大小将下降到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 ) 个字节。所以它成为目标文件本身的一部分。(可以通过-Sswitch gcc -S -fverbose-asm t1.c编译生成程序集)


但为什么是 129 MB?
   1<< n= 2^n (1 左移 n 次)。
 => 1<<25=2^25。
     现在 1 个整数 = 4 个字节 =2^2 个字节
 => 2^25 整数=2^27 字节=2^7 * 1 M 字节= 128 MB
    

有关更多详细信息,请参阅:


*注1:严格来说,它是一个目标文件

注2:正如评论中所指出的,还可以注意到,即使可执行文件是7.3K,进程(正在执行的程序)的总大小也将是129Mb。(一旦程序开始执行,内存将被分配)。top您可以使用该命令查看程序的内存使用情况。

注 3:值得强调的是,这仅是因为 t 是全局的。函数本地数据的分配仍然发生在堆栈上的运行时。因此,如果t是本地的,目标文件将只占用 7.3K。

注 4:初始化static的局部变量,如初始化的全局变量,也保存在data段中。static全局与全局相同,只是您将变量的范围限制为仅当前文件。

于 2012-12-13T09:28:10.620 回答