2

I have a process with main() only and a lookup table that is mostly empty:

    int arr[10] = {0, 0, 0, 0, 1, 0, 0, 1, 0, 0};

When I put this array in global area outside of main() and compile with gcc -O2 file.c, I get the following executable:

    bash# size a.out
       text    data     bss     dec     hex filename
       1135     616       8    1759     6df a.out

When I put this array inside main() function and compile with gcc -O2 file.c, I get the following executable:

    bash# size a.out
       text    data     bss     dec     hex filename
       1135     560       8    1703     6a7 a.out

Then, I change the size of the array to 10000, without modifying the contents, and run the test again. This time the results are:

Outside main():

    bash# size a.out
       text    data     bss     dec     hex filename
       1135   40576       8   41719    a2f7 a.out

Inside main():

    bash# size a.out
       text    data     bss     dec     hex filename
       1135     560       8    1703     6a7 a.out

Why the optimization is not working when the array is in global area. Is there a way to keep a large mostly empty lookup table in global area and still have it optimized??

3
  • 1
    Are you using the array when it is declared in main? If it is unreferenced the optimizer probably omits it completely. Commented Nov 27, 2018 at 23:46
  • Try making liberal use of the const keyword? Commented Nov 27, 2018 at 23:47
  • @Richard I tried using const and this increases the .text area instead of .data but still no optimization observed. It takes a lot of space from the .text area for a very big but mostly empty array. Commented Nov 28, 2018 at 21:13

1 Answer 1

1
/*have it start emtpy so it can go into .bss*/
int arr[10000];

//__attribute__((constructor))
void arr__init(void)
{
    //set the ones
    arr[4]=1; arr[7]=1; 
}

int main()
{
    //call the initializer
    //(or uncomment the constructor attr to have it called before main automatically (nonstandard))
    arr__init();
    return arr[4]+arr[7]+arr[2];
}

size call on the object file:

text       data     bss     dec     hex filename
148       0   40000   40148    9cd4 a.out
Sign up to request clarification or add additional context in comments.

6 Comments

Not all compilers (I'm thinking GHS powerpc compilers) will put arr into .bss when given an initial value (even if zero). Should just leave out the initial value.
@Fred Good point. Also ran into compilers that switch from .bss to .data even if the initializer was empy/zero.
That doesnt make sense.. You actually proved that no optimization happens... 40000 bytes makes sizeof(int)*10000, so where is the optimization exactly?
@ErectCrested Size of the executable. Bytes in .bss won't increase it, whereas bytes in other sections will. There won't be any difference at runtime, of course.
@PSkocik from wikipedia: "The size that BSS will require at runtime is recorded in the object file, but BSS (unlike the data segment) doesn't take up any actual space in the object file". So if I understand correctly the program will allocate this when it is executed. But why optimization works (size no changed at all in .data) only when the array size is increased in main()? if it is increased in .bss the total ammount of memory is also increased..
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.