Register variables doubt

V

Vashna

Hi Group,

I have a doubt about register variables.

I know that if we have a variable used very frequently in a function,
then provided we never apply the & function to it, we can define it as a
register variable and this will make it much faster to access.

Now the question is: obviously there are only a fixed number of
registers in our CPU, maybe 6 or something. So how do we choose which
variables to define as register variables? Obviously things like loop
counters or frequently accessed pointers we must define as register, but
what other criteria do people use?

Thanks.
 
M

Mark Bluemel

Vashna said:
Hi Group,

I have a doubt about register variables.

I know that if we have a variable used very frequently in a function,
then provided we never apply the & function to it, we can define it as a
register variable and this will make it much faster to access.

Now the question is: obviously there are only a fixed number of
registers in our CPU, maybe 6 or something. So how do we choose which
variables to define as register variables? Obviously things like loop
counters or frequently accessed pointers we must define as register, but
what other criteria do people use?

http://www.c-faq.com is the Frequently Asked Questions database for this
newsgroup.

You probably need to start with Question 20.13
 
S

santosh

Vashna said:
Hi Group,

I have a doubt about register variables.

I know that if we have a variable used very frequently in a function,
then provided we never apply the & function to it, we can define it as a
register variable and this will make it much faster to access.

Furthermore external objects are not permitted to be qualified with
register.

Also stating with certainty that an object qualified with register will be
accessed "much faster" is not correct. The compiler is free to ignore the
qualifier.
Now the question is: obviously there are only a fixed number of
registers in our CPU, maybe 6 or something. So how do we choose which
variables to define as register variables? Obviously things like loop
counters or frequently accessed pointers we must define as register, but
what other criteria do people use?

With most modern compilers programmers do not use the register qualifier at
all. The reason is that the compiler's optimiser is likely to almost always
to better register allocation than the programmer.
 
G

Gordon Burditt

I have a doubt about register variables.
I know that if we have a variable used very frequently in a function,
then provided we never apply the & function to it, we can define it as a
register variable and this will make it much faster to access.

You should not know that it will make it faster, that it will make
it much faster, nor that it will make it slower or much slower.
But it might. The compiler is free to ignore the register declaration
entirely.
Now the question is: obviously there are only a fixed number of
registers in our CPU, maybe 6 or something. So how do we choose which
variables to define as register variables?

I generally let the compiler do its job and define none. Dedicating
a register might slow down other calculations that need it more.
Obviously things like loop
counters or frequently accessed pointers we must define as register, but
what other criteria do people use?

If you have MEASURED the performance both ways, and register improves
performance, go ahead and use it, but be prepared to MEASURE again when
moving to a different platform / compiler / OS.
 
P

Philip Potter

Vashna said:
Hi Group,

I have a doubt about register variables.

I know that if we have a variable used very frequently in a function,
then provided we never apply the & function to it, we can define it as a
register variable and this will make it much faster to access.

Now the question is: obviously there are only a fixed number of
registers in our CPU, maybe 6 or something. So how do we choose which
variables to define as register variables? Obviously things like loop
counters or frequently accessed pointers we must define as register, but
what other criteria do people use?

As others have said, register is freely ignored by the compiler, and the
compiler almost always does a better job of register allocation than the
programmer. If a variable would be better stored in a register, the
compiler will work that out for you and put it there.

Just don't use the 'register' keyword. Like 'auto', there is no need for
it. (Unlike 'auto', it is conceivable that in some old compilers there
was a need for 'register'.)
 
P

pete

Vashna said:
Hi Group,

I have a doubt about register variables.

I know that if we have a variable used very frequently in a function,
then provided we never apply the & function to it,
we can define it as a
register variable and this will make it much faster to access.

Now the question is: obviously there are only a fixed number of
registers in our CPU, maybe 6 or something. So how do we choose which
variables to define as register variables?

We can only choose which variables to define as register variables
for specific C implementations.
Obviously things like loop
counters or frequently accessed pointers we must define as register,

No.
The register keyword is *not* something that can be used
to good effect for a program which is intended
to run on arbitrary C implementations.
but what other criteria do people use?

The register keyword tells the compiler
that the code writer thinks that he knows
more about optimization than the compiler does.

Use the register keyword when you know more
about optimization than your compiler does;
and get ready to remove the register keyword from your code
if the code is supposed to be able to run on other C implementations.
 
C

CBFalconer

pete said:
We can only choose which variables to define as register
variables for specific C implementations.


No. The register keyword is *not* something that can be used
to good effect for a program which is intended to run on
arbitrary C implementations.


The register keyword tells the compiler
that the code writer thinks that he knows
more about optimization than the compiler does.

Use the register keyword when you know more
about optimization than your compiler does;
and get ready to remove the register keyword from your code
if the code is supposed to be able to run on other C implementations.

You have it all wrong. The register keyword may always be ignored
by the compiler, with the sole exception that it makes taking the
address of the object impossible. This allows the compiler to
completely control the optimization. So using it (register) is
pointless, except on some ancient compilers that can't do
optimization at all.
 
K

Keith Thompson

CBFalconer said:
pete wrote: [...]
The register keyword tells the compiler
that the code writer thinks that he knows
more about optimization than the compiler does.

Use the register keyword when you know more
about optimization than your compiler does;
and get ready to remove the register keyword from your code
if the code is supposed to be able to run on other C implementations.

You have it all wrong. The register keyword may always be ignored
by the compiler, with the sole exception that it makes taking the
address of the object impossible. This allows the compiler to
completely control the optimization. So using it (register) is
pointless, except on some ancient compilers that can't do
optimization at all.

That's the common widom, but I wonder how accurate it is.

First, here's what the standard says (C99 6.7.1p4):

A declaration of an identifier for an object with storage-class
specifier register suggests that access to the object be as fast
as possible. The extent to which such suggestions are effective is
implementation-defined.

with a footnote:

The implementation may treat any register declaration simply as an
auto declaration. However, whether or not addressable storage is
actually used, the address of any part of an object declared with
storage-class specifier register cannot be computed, either
explicitly (by use of the unary & operator as discussed in
6.5.3.2) or implicitly (by converting an array name to a pointer
as discussed in 6.3.2.1). Thus, the only operator that can be
applied to an array declared with storage-class specifier register
is sizeof.

Do modern compilers really ignore the "register" keyword (except to
prohibit taking the address of the object)? Or do some of them pay
some attention to it, at least in some modes?

It seems at least plausible that, if I've carefully profiled my code
and found that references to a particular int object are a bottleneck,
declaring it "register" at least is unlikely to hurt.
 
S

santosh

Keith said:
CBFalconer said:
pete wrote: [...]
The register keyword tells the compiler
that the code writer thinks that he knows
more about optimization than the compiler does.

Use the register keyword when you know more
about optimization than your compiler does;
and get ready to remove the register keyword from your code
if the code is supposed to be able to run on other C implementations.

You have it all wrong. The register keyword may always be ignored
by the compiler, with the sole exception that it makes taking the
address of the object impossible. This allows the compiler to
completely control the optimization. So using it (register) is
pointless, except on some ancient compilers that can't do
optimization at all.

That's the common widom, but I wonder how accurate it is.

Do modern compilers really ignore the "register" keyword (except to
prohibit taking the address of the object)? Or do some of them pay
some attention to it, at least in some modes?

<OT>
The gcc documentation on my system notes that register will likely be
honoured under the -O0 optimisation level, and as a part of a gcc
specific
extension. There is also an arcane mention of the effect of register
when
setjmp is used on certain "rare" x86 targets.

Pretty limited support for register, IMHO.
It seems at least plausible that, if I've carefully profiled my code
and found that references to a particular int object are a bottleneck,
declaring it "register" at least is unlikely to hurt.

I suppose that on most compilers an int or another basic object used
heavily
enough to be a bottleneck would already be kept in a register. This is
exactly the sort of microoptimisation, (along with inline assembler),
that
blurs the boundary between C and assembler. IME in situations where
the use
of register is appropriate are so basic as to be already covered by
most
compilers, even without an optimiser.
 
V

Vashna

Thanks for all the answers, I feel like I understand it much better now.

The only doubt I still have is: what if in a single function we define
more register variables than there are registers in the CPU? Will we get
a compile time error, or just unpredictable behavior at runtime?

(Actually I guess you may not even be able to have one register variable
for each register, if the return value of the function is passed back to
the caller in a register.)

Thanks.
 
S

santosh

Vashna said:
Thanks for all the answers, I feel like I understand it much better now.

The only doubt I still have is: what if in a single function we define
more register variables than there are registers in the CPU? Will we get
a compile time error, or just unpredictable behavior at runtime?

Neither. The implementation will simply ignore one or more or all of your
register requests.

<snip>
 
R

Richard

santosh said:
Neither. The implementation will simply ignore one or more or all of your
register requests.

This is unpredictable behaviour. Personally I think its a failing in
such a low level language not to be able to ensure register assignment
within the constraints of the HW.
 
S

santosh

Richard said:
This is unpredictable behaviour.

No it's not since the Standard explicitly excuses a conforming
implementation from guaranteeing anything with regard to the register
specifier other than disallowing taking their address.
Personally I think its a failing in
such a low level language not to be able to ensure register assignment
within the constraints of the HW.

Since C is meant to be implemented on a great variety of hardware from
those having no more than two or three to those with hundreds of
registers, how would you propose to ensure register assignment for
register qualified objects.

Register assignment is already done as a part of translation, the
register specifier is merely a "hint" from the programmer to help the
compiler's register allocator and optimiser.

Forcing implementations to honour the register specifier, even within
the constraints of the hardware, is likely to lead to worse code than
letting the compiler do the job. The compiler almost always has more
knowledge of the target architecture than an average programmer. There
is always the option of inline assembler or separately assembler
routines when an experienced programmer needs to extract specific use
of the hardware.
 
R

Richard

santosh said:
No it's not since the Standard explicitly excuses a conforming
implementation from guaranteeing anything with regard to the register
specifier other than disallowing taking their address.

I don't care what the standard says. It is unpredictable behaviour. Not
"undefined". It is unpredictable since you have NO idea if or how a
register is assigned. You correctly point out however, that one CAN go
to assembler if the glove really doesn't fit.
Since C is meant to be implemented on a great variety of hardware from
those having no more than two or three to those with hundreds of
registers, how would you propose to ensure register assignment for
register qualified objects.

I am not talking about the standard. But I would document a procedure
which implementations should follow in the standard where the registers
can be queried and assigned and forced if necessary.
Register assignment is already done as a part of translation, the
register specifier is merely a "hint" from the programmer to help the
compiler's register allocator and optimiser.

Yes, We know what it is. That is why I thought I would mention what I
think it should be rather than what it is.
Forcing implementations to honour the register specifier, even within
the constraints of the hardware, is likely to lead to worse code than
letting the compiler do the job. The compiler almost always has more

There are times when there is a damn good reason for overriding
this default compiler behaviour.
knowledge of the target architecture than an average programmer. There
is always the option of inline assembler or separately assembler
routines when an experienced programmer needs to extract specific use
of the hardware.

Very true.
 
S

santosh

Richard said:
I don't care what the standard says. It is unpredictable behaviour.
Not "undefined". It is unpredictable since you have NO idea if or how
a register is assigned. You correctly point out however, that one CAN
go to assembler if the glove really doesn't fit.

Though it's virtually non-existent today, it's always possible that
memory-to-memory processors could make a comeback. Also under RISC CPUs
like the Itanium it will become _very_ tedious and error prone for the
programmer to keep track of register allocation.

Also keep in mind that a source which makes use of your proposal will
probably need careful modification when porting from one architecture
to another or even from one implementation to another. Also the
disadvantage of not being able to derive the address of the concerned
objects might become onerous.

In summary I think, (though I may very likely be wrong), that an effort
for Standardising further constraints for register is likely to be
complex and ambiguous. Further I don't think there is enough demand in
the C programming community for this to justify the demand on
implementors and potential loss in portability.
I am not talking about the standard. But I would document a procedure
which implementations should follow in the standard where the
registers can be queried and assigned and forced if necessary.

Personally I'd prefer the Standardisation of the asm keyword and
associated semantics, as has been done with C++, than further messing
around with register.

<snip>
 
R

Richard

santosh said:
Though it's virtually non-existent today, it's always possible that
memory-to-memory processors could make a comeback. Also under RISC CPUs
like the Itanium it will become _very_ tedious and error prone for the
programmer to keep track of register allocation.

Also keep in mind that a source which makes use of your proposal will

I do keep it in mind. Hence what i said about programmatically
determining the possibilities.
probably need careful modification when porting from one architecture
to another or even from one implementation to another. Also the
disadvantage of not being able to derive the address of the concerned
objects might become onerous.

I'm not sure we are talking about the same thing. You appear to be
talking about how it is, rather than discussing the potential usefulness
of having more concrete register behaviour.
In summary I think, (though I may very likely be wrong), that an effort
for Standardising further constraints for register is likely to be
complex and ambiguous. Further I don't think there is enough demand in
the C programming community for this to justify the demand on
implementors and potential loss in portability.

How many more times : there would be no loss in portability if done
properly.
Personally I'd prefer the Standardisation of the asm keyword and
associated semantics, as has been done with C++, than further messing
around with register.

That is a ridiculous idea. Would you also propose a single ASM language
for all processors?
 
C

CBFalconer

santosh said:
.... snip ...

Personally I'd prefer the Standardisation of the asm keyword and
associated semantics, as has been done with C++, than further
messing around with register.

Rather hard unless you simultaneously restrict C to run on only one
architecture. :)
 
K

Keith Thompson

Richard said:
santosh said:
Richard said:
Vashna wrote: [...]
The only doubt I still have is: what if in a single function we
define more register variables than there are registers in the CPU?
Will we get a compile time error, or just unpredictable behavior at
runtime?

Neither. The implementation will simply ignore one or more or all of
your register requests.

This is unpredictable behaviour.

No, it's not behavior at all. The standard defines "behavior" as
"external appearance or action". Register assignment is not behavior
unless it affects the external appearance or action of the program.

[...]
I don't care what the standard says.

If you don't care what the standard says, then I don't care what you
have to say about the language.

If you want assembly language, you know where to find it.

Adding finer-grained register control to C would be a terrible
mistake.
 
K

Keith Thompson

santosh said:
Personally I'd prefer the Standardisation of the asm keyword and
associated semantics, as has been done with C++, than further messing
around with register.

C++ defines the asm keyword and its syntax:

asm ( string-literal ) ;

but leaves its semantics entirely implementation-defined.

I'm not convinced that this is useful. Any program that uses ``asm''
is inherently non-portable, and must be modified if it's to be ported
to another platform. I don't see how standardizing part of the syntax
aids portability (or anything else).
 
S

santosh

Richard said:
I'm not sure we are talking about the same thing. You appear to be
talking about how it is, rather than discussing the potential
usefulness of having more concrete register behaviour.

Okay maybe you should propose a syntax for this and cross-post it c.s.c
and here? Then we can discuss something concrete.

That is a ridiculous idea. Would you also propose a single ASM
language for all processors?

Not at all. I'm talking about including the 'asm' keyword into Standard
C, not it's actual usage. Right now we have a variety of implementation
defined keywords for inline assembler like 'asm' '_asm' '__asm__' if
the facility exists at all.
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top