Ordering local variables

B

Bob Pratchett

Can people here settle an argument?

Consider a function called in deep recursion. Clearly minimizing it's
stack usage is extremely important.

Suppose it has a number of int and char automatic variables. The
question is: will ordering their declarations like this:

int a;
char b;
int c;
char d;
....

use more memory (because of Alignment) than grouping the chars together:

int a,c,...;
char b,d,...;

Although the usual thing is for variables to be put on the stack in the
reverse order of declaration, it seems to me that a good optomizing
compiler might well be able to reorder the declarations to minimize
stack usage.

So, what do people think is the best order for automatic variable
declarations?
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Bob said:
Can people here settle an argument?

Consider a function called in deep recursion. Clearly minimizing it's
stack usage is extremely important.

Suppose it has a number of int and char automatic variables. The
question is: will ordering their declarations like this:

int a;
char b;
int c;
char d;
...

use more memory (because of Alignment) than grouping the chars together:

int a,c,...;
char b,d,...;

Although the usual thing is for variables to be put on the stack in the
reverse order of declaration, it seems to me that a good optomizing
compiler might well be able to reorder the declarations to minimize
stack usage.

Yes, there is nothing wrong with such an optimisation, and some compilers do
this.
So, what do people think is the best order for automatic variable
declarations?

I suggest you keep it in the most readable form, and if you notice a problem
_and_ you're dealing with a compiler that doesn't automatically reorder
variables, only then should you consider the order.
 
M

Malcolm McLean

Bob Pratchett said:
Can people here settle an argument?

Consider a function called in deep recursion. Clearly minimizing it's
stack usage is extremely important.

Suppose it has a number of int and char automatic variables. The
question is: will ordering their declarations like this:

int a;
char b;
int c;
char d;
...

use more memory (because of Alignment) than grouping the chars together:

int a,c,...;
char b,d,...;

So, what do people think is the best order for automatic variable
declarations?
Put like together and the larger variables towards the top.
Generally it won't make a difference, but if the compiler isn't quite
top-notch, that will give you the best chance of minimising stack usage.

Of course you can also usually make all but one parameter global. Not in the
call that you expose to the user, but in your private file.
 
A

adam.wieckowski

Can people here settle an argument?

Consider a function called in deep recursion. Clearly minimizing it's
stack usage is extremely important.

Suppose it has a number of int and char automatic variables. The
question is: will ordering their declarations like this:

int a;
char b;
int c;
char d;
...

use more memory (because of Alignment) than grouping the chars together:

int a,c,...;
char b,d,...;

Although the usual thing is for variables to be put on the stack in the
reverse order of declaration, it seems to me that a good optomizing
compiler might well be able to reorder the declarations to minimize
stack usage.

So, what do people think is the best order for automatic variable
declarations?

Hmm... I've done some research.
Here's the test suite:

###

#include <stdio.h>

void abc(int);
int do_int(int);
char do_char(char);

int main(void)
{
abc(1);
}

void abc(int x)
{
int a = do_int(1);
char b = do_char('b');
int c = do_int(2);
char d = do_char('d');

printf("%llu, %llu, %llu, %llu\n", &a, &b, &c, &d);
if(x < 5) abc(x+1);
}

int do_int(int a)
{
return a;
}

char do_char(char a)
{
return a;
}

###

I've compiled it 4 times. 2x with gcc, once with and once without -O2.
And 2x with Sun C Compiler (sunc99), once with and once without -O2.

Here are the results:

adam@localhost ~/devel/c $ ./sun_func_reorder
140734035459724, 140734035459723, 140734035459716, 140734035459715
140734035459676, 140734035459675, 140734035459668, 140734035459667
140734035459628, 140734035459627, 140734035459620, 140734035459619
140734035459580, 140734035459579, 140734035459572, 140734035459571
140734035459532, 140734035459531, 140734035459524, 140734035459523
adam@localhost ~/devel/c $ ./sun_opt_func_reorder
140734553816272, 140734553816279, 140734553816280, 140734553816287
140734553816208, 140734553816215, 140734553816216, 140734553816223
140734553816144, 140734553816151, 140734553816152, 140734553816159
140734553816080, 140734553816087, 140734553816088, 140734553816095
140734553816016, 140734553816023, 140734553816024, 140734553816031
adam@localhost ~/devel/c $ ./gcc_func_reorder
140736836242876, 140736836242875, 140736836242868, 140736836242867
140736836242828, 140736836242827, 140736836242820, 140736836242819
140736836242780, 140736836242779, 140736836242772, 140736836242771
140736836242732, 140736836242731, 140736836242724, 140736836242723
140736836242684, 140736836242683, 140736836242676, 140736836242675
adam@localhost ~/devel/c $ ./gcc_opt_func_reorder
140736016752680, 140736016752687, 140736016752676, 140736016752686
140736016752648, 140736016752655, 140736016752644, 140736016752654
140736016752616, 140736016752623, 140736016752612, 140736016752622
140736016752584, 140736016752591, 140736016752580, 140736016752590
140736016752552, 140736016752559, 140736016752548, 140736016752558

As you see, sun's compiler never reorders functions variables. Gcc
does, with -O2, otherwise also not. Mind, that if I'm not reading
variable addresses, the variables are not at all hold on stack at
execution time, but in registers. Than, after the execution they're
pushed onto the stack (but then, in all 4 cases they are treated as
normal integers). Try to compile program with

< printf("%llu, %llu, %llu, %llu\n", &a, &b, &c, &d);
printf("%i, %c, %i, %c\n", a, b, c, d);

And analyze the disassembled output. It reveals what I've just said:

4004c0: 41 56 push %r14
4004c2: 41 55 push %r13
4004c4: 41 54 push %r12
4004c6: 55 push %rbp
...
400522: 5d pop %rbp
400523: 41 5c pop %r12
400525: 41 5d pop %r13
400527: 41 5e pop %r14

(mind, I'm amd64).

So, well, it's not that obvious as I actually firstly though it
would...
Well, hope this was helpful.

Adam
 
B

Boudewijn Dijkstra

Op Sun, 09 Sep 2007 18:58:31 +0200 schreef Harald van Dijk
I suggest you keep it in the most readable form, and if you notice a
problem

_and_ your machine supports char-sized stack elements
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,614
Members
45,290
Latest member
JennaNies

Latest Threads

Top