For program from http://bellard.org/mersenne.html GCC produces ~130MB executable. Why?
Try changing t[1<<25]={2}
to t[1<<25]
and the size of the *executable** will drop down to 7.3 K. (Needless to say, you won't get the right results)
If it was just t[1<<25]
, it wouldn't have taken any space at all.
The catch here is that the array is being initialized (first element=2, the next 2^25-1 elements all 0), and the global array gets placed in the data segment only because it is initialized.
[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
As we can notice, in the original version, the assembler is directed to generate 2^27 (134217728 ) bytes in the data segment. So it becomes a part of the object file itself. ( You can generate assembly by compiling with -S
switch 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
Note 2: As pointed out in the comments, It may also be noted that the total size of the process (program in execution) will be 129Mb even if the executable is of 7.3K. (The memory will be allocated once the program starts executing). You can see the memory usage of your program by using the top
command.
Note 3: It is worth emphasizing that this holds only because t is global. Allocation for data local to a function still happens at runtime on the stack. So if t
was local, the object file would've taken 7.3K only.
Note 4: Initialized static
local variables, like initialized globals, are also kept in the data
segment. A static
global is same as a global except that you are limiting the scope of the variable to the current file only.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With