views:

249

answers:

5

Hi,

I have something like this

register unsigned int a, b, c;
int n;
for (n = 0; n < 10; ++n){
c = a + b
b = a
a = c
array[n] = c;
}

what it does, it doesn't matter. The code runs quickly the way it is now, slower if the register keyword is removed. However, when I add in register before int n, it actually runs slower than now, but faster than if no registers is used.

Can someone explain this to me? Thanks.

+6  A: 

register gives the compiler a hint to place the variable in a register instead of memory/stack space. In some cases, there won't be enough registers for every variable you place this keyword on so placing it on too many variables can force some of the others out of registers again.

This is just a hint, though, and the compiler doesn't have to take it.

SoapBox
It also means you can't pass the variable by address - or shouldn't do so because a variable in a register has no address.
Jonathan Leffler
Passing a `register` variable by address simply tells the compiler to spill it to stack. It's quite legal in C++ (but not ANSI C).
Crashworks
+8  A: 

How did you time this? In practice, register usually does nothing. It's a piece of cruft from when compiler technology was extremely primitive and compilers couldn't figure out register allocation themselves. It was supposed to be a hint to allocate a register to that variable and was useful for variables used very frequently. Nowadays, most compilers simply ignore it and allocate registers according to their own algorithms.

dsimcha
I've heard many places that this flag is ignored, but I've never seen anything to back this up other than rumor. Do you happen to have sources? In my experience with gcc this flag can sometimes make a difference (though I admit that difference is usually negative).
SoapBox
@soap dsimcha is right, it is a relic of times gone by. wiki it google it etc -- you will find your proof.
Hassan Syed
but the fact is that I calculated the time and I am getting the result like I said in the problem
SuperString
How did you "calcuate" the time? Can you post the generated assembly for each version?
Anon.
It makes a difference in gcc when optimisations are turned off (reference: http://gcc.gnu.org/onlinedocs/gcc/Hints-implementation.html).
Matthew Slattery
Though one would wonder why you're trying to "optimize" with `register` when you're compiling without optimizations.
Anon.
It is deprecated in C++0x, oops, 1x: http://www-949.ibm.com/software/rational/cafe/blogs/cpp-standard/2009/11/06/to-derprecate-or-not-deprecate-that-is-the-question
Hans Passant
+1  A: 

There are a limited number of registers available, so marking everything as register won't put everything in registers. Benchmarking is the only way to know if it's going to help or not. A good compiler should be able to figure out what variables to put into registers on its own, so you should probably benchmark some more before you decide that the register keywords helps.

Amuck
"Benchmarking is the only way to know if it's going to help or not". Well, he says he has benchmarked, and that he's come up with results for three different cases. If his benchmarks are incorrect, then telling him to benchmark again won't make them correct ;-)
Steve Jessop
It seems strange that there would be a difference since an optimizing compiler should know which variables should go into registers, so I think it's wise to benchmark again to make sure it's done right.
Amuck
A: 

There's a limit to allocatable registers. If you outgo it, you just end up with less efficient code.

My take is that if what you do is so important that you have to decide yourself what goes in a register and what doesn't, you should write it using assembly language.

For general purpose languages, I strongly believe that a compiler is better able to decide what goes in a register than a human. The proof being that while you're not sure how many variables you can put in registers, your compiler knows for sure.

zneak
A: 

In gcc, register is definitely not ignored, unless you specify optimization options. Testing your code with something like this

unsigned int array[10];

int n;

#define REG register

int main()
{
    REG unsigned int a, b, c;

    for (n = 0; n < 10; ++n){
        c = a + b;
        b = a;
        a = c;
        array[n] = c;
    }
}

you obtain (depending on whether REG is defined or empty) diff http://picasaweb.google.com/lh/photo/v2hBpl6D-soIdBXUOmAeMw?feat=directlink

On the left is shown the result of using registers.

dtmilano
At what optimization level is it ignored?
Potatoswatter
This depends on the code being optimized. Check the assembler generated in your particular case.
dtmilano