473,322 Members | 1,526 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

Register keyword and "as if" rule...

With the "as if" rule in play, doesn't that effectively render the
"register" keyword completely useless?

Example: I make a silly compiler which creates code that goes out of
its way to take a full 10 minutes every time a "register" declared
variable is read from or written to. Besides this lag, everything else
runs as expected. Then my compiler is still C compliant, aye?

If so, then it is unwise for any programmer to ever use the "register"
keyword if they want their code to run smoothly on all implementations:
their programs might get compiled by my silly compiler someday, and
then they'll be really blushing :*)

Or, more realistically, my compiler could simply ignore the "register"
keyword outright (except to issue diagnostics if it were used in a
syntactically bad way or its namespace violated).

Or does the standard actually make some assumption that the
implementation has things called "registers"?

Oct 13 '06 #1
33 3219
Snis Pilbor said:
With the "as if" rule in play, doesn't that effectively render the
"register" keyword completely useless?

Example: I make a silly compiler which creates code that goes out of
its way to take a full 10 minutes every time a "register" declared
variable is read from or written to. Besides this lag, everything else
runs as expected. Then my compiler is still C compliant, aye?
Yes. It would still be conforming if it went out of its way to take a full
10 minutes every time you read from or wrote to an object that was *not*
register-qualified. So the argument is spurious.
If so, then it is unwise for any programmer to ever use the "register"
keyword if they want their code to run smoothly on all implementations:
That isn't a reason not to bother with register. The best reason not to
bother with register is that modern compilers are far better at deciding
what to put into registers than the vast majority of programmers.
their programs might get compiled by my silly compiler someday, and
then they'll be really blushing :*)
More likely you will be. :-)
>
Or, more realistically, my compiler could simply ignore the "register"
keyword outright (except to issue diagnostics if it were used in a
syntactically bad way or its namespace violated).
Many compilers behave in precisely this way.
Or does the standard actually make some assumption that the
implementation has things called "registers"?
No, it simply specifies the syntax, and leaves the decision up to the
implementor.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 13 '06 #2

Snis Pilbor wrote:
With the "as if" rule in play, doesn't that effectively render the
"register" keyword completely useless?

Example: I make a silly compiler which creates code that goes out of
its way to take a full 10 minutes every time a "register" declared
variable is read from or written to. Besides this lag, everything else
runs as expected. Then my compiler is still C compliant, aye?

If so, then it is unwise for any programmer to ever use the "register"
keyword if they want their code to run smoothly on all implementations:
their programs might get compiled by my silly compiler someday, and
then they'll be really blushing :*)

Or, more realistically, my compiler could simply ignore the "register"
keyword outright (except to issue diagnostics if it were used in a
syntactically bad way or its namespace violated).

Or does the standard actually make some assumption that the
implementation has things called "registers"?
For the past ten years, the register keyword has been useless anyway.

The compiler will choose what should be a register and what should not
better than you will (if the compiler is any good).

By naming something as a register, certain operations become impossible
(e.g. you can't take the address of a register).

The same thing goes for 'inline' which was obsolete before it was
formally introduced.

Optimization hints in general are not nearly so important as they were
20 years ago.

Oct 13 '06 #3
Snis Pilbor wrote:
is unwise for any programmer to ever use the "register"
keyword if they want their code to run smoothly on all
mplementations
The register keyword tells the compiler
that you think that you know more about optimization
than the compiler does.

The only way to use "register" effectively,
is on a per implementation basis with timed tests.

--
pete
Oct 14 '06 #4
Richard Heathfield wrote:
That isn't a reason not to bother with register. The best reason not to
bother with register is that modern compilers are far better at deciding
what to put into registers than the vast majority of programmers.
I have read that claim many times. While it may be true, I would rather
the compiler honor the request when made so that the careful programmer
has the opportunity to improve his generated code. I don't care that a
careless programmer can easily make it worse. Unfortunately (in my
opinion), most modern compilers ignore that hint.

The one thing that the programmer can know that the compiler doesn't is
the relative frequency of execution paths, which may be important for
choosing the proper register allocation.

--
Thad
Oct 14 '06 #5
Thad Smith <Th*******@acm.orgwrites:
Richard Heathfield wrote:
>That isn't a reason not to bother with register. The best reason not to
bother with register is that modern compilers are far better at deciding
what to put into registers than the vast majority of programmers.

I have read that claim many times. While it may be true, I would rather
the compiler honor the request when made so that the careful programmer has
the opportunity to improve his generated code. I don't care that a
careless programmer can easily make it worse. Unfortunately (in my
opinion), most modern compilers ignore that hint.
The carefull programmer of yesterday make it impossible to get correct
performance from his code in today's implementation if the implementation
were to honor his request.

Yours,

--
Jean-Marc
Oct 14 '06 #6
"Richard Heathfield" <in*****@invalid.invalidwrote in message
>
That isn't a reason not to bother with register. The best reason not to
bother with register is that modern compilers are far better at deciding
what to put into registers than the vast majority of programmers.
If you were writing a compiler, how would you use the keyword? Given that
we've got a spare word that won't break old programs.
--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.
Oct 14 '06 #7
"Malcolm" <re*******@btinternet.comwrites:
"Richard Heathfield" <in*****@invalid.invalidwrote in message
>That isn't a reason not to bother with register. The best reason not to
bother with register is that modern compilers are far better at deciding
what to put into registers than the vast majority of programmers.
If you were writing a compiler, how would you use the keyword? Given that
we've got a spare word that won't break old programs.
For starters, the guarantee that the object's address will never be
taken could introduce some opportunities for optimizations (though for
local variables the compiler can probably figure that out for itself).

I might ignore it by default, or perhaps give it some small weight in
deciding whether to assign a variable to a register, but provide a
command-line option to assign a higher weight.

This assumes, of course, that my optimizer really is better at
register allocation than most programmers; I'd want to test that
assumption on some real code before making a final decision on what
the default behavior should be.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 14 '06 #8
Thad Smith wrote:
Richard Heathfield wrote:
>That isn't a reason not to bother with register. The best reason not
to bother with register is that modern compilers are far better at
deciding what to put into registers than the vast majority of
programmers.


I have read that claim many times. While it may be true, I would rather
the compiler honor the request when made so that the careful programmer
has the opportunity to improve his generated code. I don't care that a
careless programmer can easily make it worse. Unfortunately (in my
opinion), most modern compilers ignore that hint.
As a careful programmer, you no doubt made a careful series
of measurements to figure out which variables merit `register'
and which do not. You may even have discovered some variables
for which adding `register' slows down the code -- for example,
by forcing a save/restore the compiler would not otherwise have
generated, or by depriving the compiler of scratch registers it
could have used for other purposes. (I have seen this happen,
back in the Bad Old Days when `register' was the C programmer's
"abracadabra.")

But all your measurements are inextricably tied to just one
version of one compiler on one machine. As a careful programmer,
then, you need to repeat your measurements on the other platforms
of interest, and use #if magic so that you'll get optimal code
from gcc and Visual C++ and Frobozz Magic C, on Xeon and Opteron
and PowerPC and DS9000. And you'll need to do the whole job over
again when you patch or upgrade a compiler, or when a faster model
of a processor chip changes the relative costs of register- and
memory-resident data ...

A question: If the last smidgen of speed is so important to
you that you're willing to become the slave of the machine instead
of 'tother way about, why are you messing around with compiled
languages in the first place? Shouldn't you be writing machine
code, or at the very least assembly code?

I am not claiming that micro-optimization in general and
`register' in particular are always bad ideas, but I do claim
that they are seldom good ideas. The techniques developed
thirty years ago have been largely overtaken by the economics
of progress: CPU cycles used to be costlier than programmer
cycles, but the balance is now reversed. Corner cases will
always be with us, but the corners have been shrinking.
The one thing that the programmer can know that the compiler doesn't is
the relative frequency of execution paths, which may be important for
choosing the proper register allocation.
Compilers *can* know this, and with more accuracy than the
programmer is usually able to provide. The compiler instruments
the compiled code, you run the program over your universe of test
cases to generate counts and stuff, and finally you recompile
using both the source and the "feedback" data. This was cutting-
edge stuff fifteen years ago, and commercial compilers have been
using the technique for at least a decade.

--
Eric Sosman
es*****@acm-dot-org.invalid
Oct 14 '06 #9

Richard Heathfield wrote:
That isn't a reason not to bother with register. The best reason not to
bother with register is that modern compilers are far better at deciding
what to put into registers than the vast majority of programmers.

Well, generally yes, but sometimes, NO.

The glitch in the ointment is that optimizing compilers try to minimize
the overall run time.

That's really keen and swell if you care about the time from engine
start to hitting the pub.

But there are many real-world situations where certain snippets of
code HAVE to run as fast as possible, in order to keep screens from
flickering, while maybe 95% of the code, being background or keypress
handling code, could be running at interpreted COBOL speeds. A
flight-control computer is a good example-- the keypresses come in very
rarely, but managing the rudder position had better happen every
millisecond.

But your typical compiler will try to speedup ALL the code, which in a
register-tight environment, such as the x86, means every register the
compiler allocates to a keyboard key handling loop, is a register that
won't be available for the rudder-damping code (assuming there's a
minimum of slow register save/restores being done).

So in those cases where pinpoint optimization is really needed, hints
like "register" might be appropriate.

Oct 14 '06 #10

"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
"Malcolm" <re*******@btinternet.comwrites:
>"Richard Heathfield" <in*****@invalid.invalidwrote in message
>>That isn't a reason not to bother with register. The best reason not to
bother with register is that modern compilers are far better at deciding
what to put into registers than the vast majority of programmers.
If you were writing a compiler, how would you use the keyword? Given that
we've got a spare word that won't break old programs.

For starters, the guarantee that the object's address will never be
taken could introduce some opportunities for optimizations (though for
local variables the compiler can probably figure that out for itself).

I might ignore it by default, or perhaps give it some small weight in
deciding whether to assign a variable to a register, but provide a
command-line option to assign a higher weight.

This assumes, of course, that my optimizer really is better at
register allocation than most programmers; I'd want to test that
assumption on some real code before making a final decision on what
the default behavior should be.
I meant, how wouold you extend the keyword.
For instnace, we could use "register" to register a pointer for bounds
checking. It would be perfectly compliant, but extend the language in a
useful way.
--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.

Oct 14 '06 #11
"Malcolm" <re*******@btinternet.comwrites:
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
>"Malcolm" <re*******@btinternet.comwrites:
>>"Richard Heathfield" <in*****@invalid.invalidwrote in message
That isn't a reason not to bother with register. The best reason not to
bother with register is that modern compilers are far better at deciding
what to put into registers than the vast majority of programmers.

If you were writing a compiler, how would you use the keyword? Given that
we've got a spare word that won't break old programs.

For starters, the guarantee that the object's address will never be
taken could introduce some opportunities for optimizations (though for
local variables the compiler can probably figure that out for itself).

I might ignore it by default, or perhaps give it some small weight in
deciding whether to assign a variable to a register, but provide a
command-line option to assign a higher weight.

This assumes, of course, that my optimizer really is better at
register allocation than most programmers; I'd want to test that
assumption on some real code before making a final decision on what
the default behavior should be.
I meant, how wouold you extend the keyword.
For instnace, we could use "register" to register a pointer for bounds
checking. It would be perfectly compliant, but extend the language in a
useful way.
Oh, I see.

I wouldn't re-use "register". If I wanted to implement an extension,
I'd use some reserved identifier like __foobar__.

Or, if I were trying to create a new version of the standard, I'd
provide another meaning for "static". 8-)}

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 14 '06 #12
Keith Thompson wrote:
"Malcolm" <re*******@btinternet.comwrites:
>
If you were writing a compiler, how would you use the keyword? Given that
we've got a spare word that won't break old programs.

For starters, the guarantee that the object's address will never be
taken could introduce some opportunities for optimizations (though for
local variables the compiler can probably figure that out for itself).
All register variables are local variables.

Oct 14 '06 #13
"Old Wolf" <ol*****@inspire.net.nzwrites:
Keith Thompson wrote:
>"Malcolm" <re*******@btinternet.comwrites:
>>
If you were writing a compiler, how would you use the keyword? Given that
we've got a spare word that won't break old programs.

For starters, the guarantee that the object's address will never be
taken could introduce some opportunities for optimizations (though for
local variables the compiler can probably figure that out for itself).

All register variables are local variables.
Yes.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 14 '06 #14
On Fri, 13 Oct 2006 20:40:20 +0000, Richard Heathfield
<in*****@invalid.invalidwrote in comp.lang.c:
Snis Pilbor said:
With the "as if" rule in play, doesn't that effectively render the
"register" keyword completely useless?

Example: I make a silly compiler which creates code that goes out of
its way to take a full 10 minutes every time a "register" declared
variable is read from or written to. Besides this lag, everything else
runs as expected. Then my compiler is still C compliant, aye?

Yes. It would still be conforming if it went out of its way to take a full
10 minutes every time you read from or wrote to an object that was *not*
register-qualified. So the argument is spurious.
If so, then it is unwise for any programmer to ever use the "register"
keyword if they want their code to run smoothly on all implementations:

That isn't a reason not to bother with register. The best reason not to
bother with register is that modern compilers are far better at deciding
what to put into registers than the vast majority of programmers.
[snip]

Can you point to any actual tests that back up this often made and, in
my experience, totally incorrect truism?

In fact, it is relatively easily to concoct sample code that the best
optimizing compiler in the world cannot do as good a job of deciding
which local objects to keep in registers, as can a programmer who
knows the range of the data passed to the function.

Think loops whose counts depend on the value of parameters.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Oct 15 '06 #15
On Sat, 14 Oct 2006 09:21:02 -0400, Eric Sosman
<es*****@acm-dot-org.invalidwrote in comp.lang.c:
Thad Smith wrote:
Richard Heathfield wrote:
That isn't a reason not to bother with register. The best reason not
to bother with register is that modern compilers are far better at
deciding what to put into registers than the vast majority of
programmers.

I have read that claim many times. While it may be true, I would rather
the compiler honor the request when made so that the careful programmer
has the opportunity to improve his generated code. I don't care that a
careless programmer can easily make it worse. Unfortunately (in my
opinion), most modern compilers ignore that hint.

As a careful programmer, you no doubt made a careful series
of measurements to figure out which variables merit `register'
and which do not. You may even have discovered some variables
for which adding `register' slows down the code -- for example,
by forcing a save/restore the compiler would not otherwise have
generated, or by depriving the compiler of scratch registers it
could have used for other purposes. (I have seen this happen,
back in the Bad Old Days when `register' was the C programmer's
"abracadabra.")
It still is, in come cases. Perhaps not in writing tiered middleware
under a desktop GUI, but C has more uses than that.
But all your measurements are inextricably tied to just one
version of one compiler on one machine. As a careful programmer,
then, you need to repeat your measurements on the other platforms
of interest, and use #if magic so that you'll get optimal code
from gcc and Visual C++ and Frobozz Magic C, on Xeon and Opteron
and PowerPC and DS9000. And you'll need to do the whole job over
again when you patch or upgrade a compiler, or when a faster model
of a processor chip changes the relative costs of register- and
memory-resident data ...
Dann straight its tied to just one compiler on one processor. Quite
often, when writing code to be run during interrupts on systems with
hard real time requirements, that is all that matters. Once such a
system ships, the compiler version will not be changed, no matter what
new version the vendor ships.
A question: If the last smidgen of speed is so important to
you that you're willing to become the slave of the machine instead
of 'tother way about, why are you messing around with compiled
languages in the first place? Shouldn't you be writing machine
code, or at the very least assembly code?
How many times have you written interrupt service routines in C that
are executed 20,000 times per second?
I am not claiming that micro-optimization in general and
`register' in particular are always bad ideas, but I do claim
that they are seldom good ideas. The techniques developed
thirty years ago have been largely overtaken by the economics
of progress: CPU cycles used to be costlier than programmer
cycles, but the balance is now reversed. Corner cases will
always be with us, but the corners have been shrinking.
There still are, and always will be, cases where CPU cycles are the
costliest resource of all, although very few of these are appear on
the typical desktop.
The one thing that the programmer can know that the compiler doesn't is
the relative frequency of execution paths, which may be important for
choosing the proper register allocation.

Compilers *can* know this, and with more accuracy than the
programmer is usually able to provide. The compiler instruments
the compiled code, you run the program over your universe of test
cases to generate counts and stuff, and finally you recompile
using both the source and the "feedback" data. This was cutting-
edge stuff fifteen years ago, and commercial compilers have been
using the technique for at least a decade.
Sadly, you are quite wrong about the state of many commercial
compilers, especially those for the embedded market where it is often
required to extract the maximum performance out of the minimum number
of clock cycles.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Oct 15 '06 #16
On 13 Oct 2006 17:07:04 -0700, dc*****@connx.com wrote in comp.lang.c:
>
Snis Pilbor wrote:
With the "as if" rule in play, doesn't that effectively render the
"register" keyword completely useless?

Example: I make a silly compiler which creates code that goes out of
its way to take a full 10 minutes every time a "register" declared
variable is read from or written to. Besides this lag, everything else
runs as expected. Then my compiler is still C compliant, aye?

If so, then it is unwise for any programmer to ever use the "register"
keyword if they want their code to run smoothly on all implementations:
their programs might get compiled by my silly compiler someday, and
then they'll be really blushing :*)

Or, more realistically, my compiler could simply ignore the "register"
keyword outright (except to issue diagnostics if it were used in a
syntactically bad way or its namespace violated).

Or does the standard actually make some assumption that the
implementation has things called "registers"?

For the past ten years, the register keyword has been useless anyway.
Interesting assertion. Can you point to any measured test data to
back it up?
The compiler will choose what should be a register and what should not
better than you will (if the compiler is any good).
The compiler? Is there only one? What about all the others? Perhaps
you really mean "most compilers" (doubtful), "some compilers", "the
compilers I use most", or "my favorite compiler"?
By naming something as a register, certain operations become impossible
(e.g. you can't take the address of a register).
Anyone who uses the "register" keyword without knowing how the
particular compiler in use generates code for the underlying processor
platform in use is a fool, as is any user of premature optimizations.
Still a fool, but less so, if he/she does not actually measure and
verify that the optimization, be it the use of the register keyword,
the inline keyword, or various other tricks, actually improves the
executable in the desired fashion.
The same thing goes for 'inline' which was obsolete before it was
formally introduced.

Optimization hints in general are not nearly so important as they were
20 years ago.
Again, I have not seen anyone produce a link to any studies that prove
this. And like anything else about the C language, evidence that
"most compilers", or even "all compilers except one", do better than
the programmer can is not a general proof.

The register keyword, and the inline keyword, now that we have it, are
tools that can be used effectively by someone who knows (and verifies)
what they do in a particular situation. And, like virtually all
optimization techniques, they can be misused much more easily by those
who do not know what they are doing.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Oct 15 '06 #17
Jack Klein said:
On Fri, 13 Oct 2006 20:40:20 +0000, Richard Heathfield
<in*****@invalid.invalidwrote in comp.lang.c:
<snip>
>The best reason not to
bother with register is that modern compilers are far better at deciding
what to put into registers than the vast majority of programmers.

[snip]

Can you point to any actual tests that back up this often made and, in
my experience, totally incorrect truism?
I'd put the boot on the other foot, and ask the programmer who wishes to use
'register' to show that it reduces the runtime significantly[1]. If it
does, fine, let him use it.

[1] Which leads to the question "when is a runtime reduction 'significant'?"
But that's another story.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 15 '06 #18
Jack Klein <ja*******@spamcop.netwrites:
On 13 Oct 2006 17:07:04 -0700, dc*****@connx.com wrote in comp.lang.c:
[...]
>For the past ten years, the register keyword has been useless anyway.

Interesting assertion. Can you point to any measured test data to
back it up?
Do you have any measured test data to refute it?

(The question is not meant to imply that you don't have such data.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 15 '06 #19
Jack Klein wrote:
On Sat, 14 Oct 2006 09:21:02 -0400, Eric Sosman
<es*****@acm-dot-org.invalidwrote in comp.lang.c:
>>Thad Smith wrote:
>>>Richard Heathfield wrote:

That isn't a reason not to bother with register. The best reason not
to bother with register is that modern compilers are far better at
deciding what to put into registers than the vast majority of
programmers.

I have read that claim many times. While it may be true, I would rather
the compiler honor the request when made so that the careful programmer
has the opportunity to improve his generated code. I don't care that a
careless programmer can easily make it worse. Unfortunately (in my
opinion), most modern compilers ignore that hint.

As a careful programmer, you no doubt made a careful series
of measurements to figure out which variables merit `register'
and which do not. You may even have discovered some variables
for which adding `register' slows down the code -- for example,
by forcing a save/restore the compiler would not otherwise have
generated, or by depriving the compiler of scratch registers it
could have used for other purposes. (I have seen this happen,
back in the Bad Old Days when `register' was the C programmer's
"abracadabra.")
Yes, I do make such tests and measurements when it matters.
It still is, in come cases. Perhaps not in writing tiered middleware
under a desktop GUI, but C has more uses than that.
> But all your measurements are inextricably tied to just one
version of one compiler on one machine. As a careful programmer,
then, you need to repeat your measurements on the other platforms
of interest, and use #if magic so that you'll get optimal code
from gcc and Visual C++ and Frobozz Magic C, on Xeon and Opteron
and PowerPC and DS9000. And you'll need to do the whole job over
again when you patch or upgrade a compiler, or when a faster model
of a processor chip changes the relative costs of register- and
memory-resident data ...

Dann straight its tied to just one compiler on one processor. Quite
often, when writing code to be run during interrupts on systems with
hard real time requirements, that is all that matters. Once such a
system ships, the compiler version will not be changed, no matter what
new version the vendor ships.
Jack is right on. As an embedded programmer, I have a choice of
dropping to assembly or tweaking the C code to meet constraints. If I
switch compilers or processors it changes. It still can be the best
option for my product.
>
> A question: If the last smidgen of speed is so important to
you that you're willing to become the slave of the machine instead
of 'tother way about, why are you messing around with compiled
languages in the first place? Shouldn't you be writing machine
code, or at the very least assembly code?


How many times have you written interrupt service routines in C that
are executed 20,000 times per second?
That's the sort of scenario I sometimes work with, as well.
> I am not claiming that micro-optimization in general and
`register' in particular are always bad ideas, but I do claim
that they are seldom good ideas. The techniques developed
thirty years ago have been largely overtaken by the economics
of progress: CPU cycles used to be costlier than programmer
cycles, but the balance is now reversed. Corner cases will
always be with us, but the corners have been shrinking.

There still are, and always will be, cases where CPU cycles are the
costliest resource of all, although very few of these are appear on
the typical desktop.
>>>The one thing that the programmer can know that the compiler doesn't is
the relative frequency of execution paths, which may be important for
choosing the proper register allocation.

Compilers *can* know this, and with more accuracy than the
programmer is usually able to provide. The compiler instruments
the compiled code, you run the program over your universe of test
cases to generate counts and stuff, and finally you recompile
using both the source and the "feedback" data. This was cutting-
edge stuff fifteen years ago, and commercial compilers have been
using the technique for at least a decade.

Sadly, you are quite wrong about the state of many commercial
compilers, especially those for the embedded market where it is often
required to extract the maximum performance out of the minimum number
of clock cycles.
Right again. Also, there are times to minimize the maximum execution
path or only a particular portion of code, not just the overall average.
I am not aware of any such automated tools for low-end embedded
market, where execution speed may be critical.

A product developer uses a range of techniques, when needed, to achieve
project goals, including algorithm choice, selecting data precision,
changing the processor clock, dropping to assembly, changing processor
model, etc. Having the compiler do something potentially useful with
the register keyword beats ignoring it. A programmer can always abstain
from using the feature and let the compiler do its best, which is the
probably best in most, but not all, cases.

--
Thad
Oct 15 '06 #20
Richard Heathfield wrote:
Jack Klein said:

>>On Fri, 13 Oct 2006 20:40:20 +0000, Richard Heathfield
<in*****@invalid.invalidwrote in comp.lang.c:
>>>The best reason not to
bother with register is that modern compilers are far better at deciding
what to put into registers than the vast majority of programmers.

[snip]

Can you point to any actual tests that back up this often made and, in
my experience, totally incorrect truism?

I'd put the boot on the other foot, and ask the programmer who wishes to use
'register' to show that it reduces the runtime significantly[1]. If it
does, fine, let him use it.
Well, yes, that's the whole point. The programmer says that it makes a
significant difference by using the register attribute. If it doesn't,
in fact, help him meet the criteria, he will remove it (or ignore it if
he doesn't care).
[1] Which leads to the question "when is a runtime reduction 'significant'?"
When the programmer says it is! One example is the difference between
keeping up with a fixed rate, no flow control, incoming data stream or
not, but I am sure there are many others.

--
Thad
Oct 15 '06 #21
Thad Smith <Th*******@acm.orgwrites:
Richard Heathfield wrote:
[...]
>I'd put the boot on the other foot, and ask the programmer who
wishes to use 'register' to show that it reduces the runtime
significantly[1]. If it does, fine, let him use it.

Well, yes, that's the whole point. The programmer says that it makes
a significant difference by using the register attribute. If it
doesn't, in fact, help him meet the criteria, he will remove it (or
ignore it if he doesn't care).
A programmer will use the "register" keyword if he *thinks* it makes a
significant difference.
>[1] Which leads to the question "when is a runtime reduction
'significant'?"

When the programmer says it is! One example is the difference between
keeping up with a fixed rate, no flow control, incoming data stream or
not, but I am sure there are many others.
When a *competent* programmer says it is. Not all programmers are
sufficiently competent to know when "register" is actually useful.

A runtime reduction is significant when it's significant, whether the
programmer says so or not.

(I'm not commenting on any programmers posting here.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 15 '06 #22
Keith Thompson <ks***@mib.orgwrites:
Thad Smith <Th*******@acm.orgwrites:
>Richard Heathfield wrote:
[...]
>>I'd put the boot on the other foot, and ask the programmer who
wishes to use 'register' to show that it reduces the runtime
significantly[1]. If it does, fine, let him use it.

Well, yes, that's the whole point. The programmer says that it makes
a significant difference by using the register attribute. If it
doesn't, in fact, help him meet the criteria, he will remove it (or
ignore it if he doesn't care).

A programmer will use the "register" keyword if he *thinks* it makes a
significant difference.
"register" has another side purpose too : it tells the reader/maintainer
what the original programmer saw as the critical data structure/pointer
- regardless of whether it really was effective at reducing run time or
not. Nothing wrong with "hints" like that when tracking down issues in
older legacy code and documentation/comments are minimum.
Oct 15 '06 #23
Keith Thompson wrote:
Thad Smith <Th*******@acm.orgwrites:
>>Richard Heathfield wrote:
>>>I'd put the boot on the other foot, and ask the programmer who
wishes to use 'register' to show that it reduces the runtime
significantly[1]. If it does, fine, let him use it.

Well, yes, that's the whole point. The programmer says that it makes
a significant difference by using the register attribute. If it
doesn't, in fact, help him meet the criteria, he will remove it (or
ignore it if he doesn't care).

A programmer will use the "register" keyword if he *thinks* it makes a
significant difference.
Right. And if it matters, he verifies and makes adjustments to get the
best results. It's another tool.
>>>[1] Which leads to the question "when is a runtime reduction
'significant'?"

When the programmer says it is! One example is the difference between
keeping up with a fixed rate, no flow control, incoming data stream or
not, but I am sure there are many others.

When a *competent* programmer says it is. Not all programmers are
sufficiently competent to know when "register" is actually useful.
Should we write compilers for competent programmers that can, in
critical situations, benefit from the assist, or only incompetent
programmers and non-critical tasks? I would prefer compilers that
benefit both, providing a good automatic optimization and register
allocation by default and honoring requests such as explicit register
allocation when requested.

I don't understand the argument that because register isn't needed in
most situations and some programmers cannot use it wisely that it
shouldn't be provided. I suppose the compiler could provide a option
switch that says ignore register requests and make it on by default.

--
Thad
Oct 15 '06 #24
Thad Smith <Th*******@acm.orgwrites:
Keith Thompson wrote:
>Thad Smith <Th*******@acm.orgwrites:
>>>Richard Heathfield wrote:
[snip]
>>>>[1] Which leads to the question "when is a runtime reduction
'significant'?"

When the programmer says it is! One example is the difference between
keeping up with a fixed rate, no flow control, incoming data stream or
not, but I am sure there are many others.
When a *competent* programmer says it is. Not all programmers are
sufficiently competent to know when "register" is actually useful.

Should we write compilers for competent programmers that can, in
critical situations, benefit from the assist, or only incompetent
programmers and non-critical tasks? I would prefer compilers that
benefit both, providing a good automatic optimization and register
allocation by default and honoring requests such as explicit register
allocation when requested.
That sounds reasonable (unless compilers are *universally* better than
programmers at register allocation).
I don't understand the argument that because register isn't needed in
most situations and some programmers cannot use it wisely that it
shouldn't be provided. I suppose the compiler could provide a option
switch that says ignore register requests and make it on by default.
Personally, I've never made such an argument.

The common wisdom is that "register" is no longer useful, and can
often be harmful, because the compiler is likely to be better than the
programmer at deciding which variables should be assigned to
registers. I've never seen enough hard data *either way* to know
whether that's actually true. (Then again, I've never really looked
for such data.)

One advantage an optimizing compiler has is that it can re-analyze the
entire program every time it's compiled. If some seemingly irrelevant
modification changes the program's behavior in such a way that
performance can be improved by putting *this* variable rather than
*that* variable in a register, the compiler can do so; it can even
make far-reaching changes in the generated code in response to a small
change in the source. A programmer typically lacks (or *should* lack)
the patience to do that kind of thing.

But that doesn't necessarily argue against the use of "register";
rather it implies that optimization should be a joint effort between
the programmer and the compiler -- with the compiler doing the bulk of
the grunt work whenever possible.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 15 '06 #25
On Sun, 15 Oct 2006 04:49:24 GMT, Keith Thompson <ks***@mib.orgwrote
in comp.lang.c:
Jack Klein <ja*******@spamcop.netwrites:
On 13 Oct 2006 17:07:04 -0700, dc*****@connx.com wrote in comp.lang.c:
[...]
For the past ten years, the register keyword has been useless anyway.
Interesting assertion. Can you point to any measured test data to
back it up?

Do you have any measured test data to refute it?

(The question is not meant to imply that you don't have such data.)
Yes, for a wide variety of embedded compilers and for some PC based
ones, for specific situations. Going into detail would be off-topic
here.

But suffice it to say that the use of the register, inline, and
restrict keywords are nothing more or less than optimizations
techniques. Like all such techniques they are often used prematurely
and improperly. And like all such techniques, they can be used
properly and tested to verify that they do indeed achieve the desired
optimization.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Oct 16 '06 #26
pete wrote:
>
Snis Pilbor wrote:
is unwise for any programmer to ever use the "register"
keyword if they want their code to run smoothly on all
mplementations

The register keyword tells the compiler
that you think that you know more about optimization
than the compiler does.
Compilers have gotten smarter over the years in terms of
optimization, while the human programmers haven't improved
that much. (Okay, the programmers writing the compiler
optimizers have learned more about optimizations, and in
doing so have made the compilers "smarter", while those
who use the compilers haven't improved siginificantly in
the area of optimization techniques.)
The only way to use "register" effectively,
is on a per implementation basis with timed tests.
In most "modern" compilers, the only likely effect of the
register keyword is that you are forbidden from taking the
arress of the variable, even if the compiler decides to not
use a register for it. (Remember the "as if" rule.)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Oct 16 '06 #27
Kenneth Brody <ke******@spamcop.netwrites:
[...]
In most "modern" compilers, the only likely effect of the
register keyword is that you are forbidden from taking the
arress of the variable, even if the compiler decides to not
use a register for it. (Remember the "as if" rule.)
The "as if" rule doesn't really apply here. Despite the spelling of
the keyword, "register" doesn't tell the compiler to store the
object in a register.

C99 6.7.1:

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.

And 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.

Hmm, I just noticed that sentence that "The extent to which such
suggestions are effective is implementation-defined." That means the
implementation is required to document it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 16 '06 #28
Jack Klein wrote:
On Sun, 15 Oct 2006 04:49:24 GMT, Keith Thompson <ks***@mib.orgwrote
in comp.lang.c:
Jack Klein <ja*******@spamcop.netwrites:
On 13 Oct 2006 17:07:04 -0700, dc*****@connx.com wrote in comp.lang.c:
[...]
>For the past ten years, the register keyword has been useless anyway.
>
Interesting assertion. Can you point to any measured test data to
back it up?
Do you have any measured test data to refute it?

(The question is not meant to imply that you don't have such data.)

Yes, for a wide variety of embedded compilers and for some PC based
ones, for specific situations. Going into detail would be off-topic
here.
I expect that my experience is different because I program large
systems (typically hundreds of thousands to millions of lines of code).

Register allocation is provably NP-hard, and is solved by very compute
intensive algorithms like graph coloring (though linear scan looks
promising for some situations):
http://www.research.ibm.com/jalapeno...s/toplas99.pdf
There are some savants and incredibile calculators like "brain man":
http://www.abc.net.au/catalyst/stories/s1740757.htm
who might have some faint chance of outcalculating the algorithms used
in register allocation for a medium sized system, but I doubt that any
such instance has ever come about (for systems with hundreds of
thousands of lines or more) that would be able to outthink current
compilers.

For a large software system, no human on earth has the ability to
out-think the compiler when it comes to register allocation.

On the other, other hand, embedded compilers may be primitive in their
ability to optimize register allocation and the embedded software
systems tend to be very small so in such a circumstance it may be
possible to do better than the compiler. On rare circumstances, when
measurements indicated a problem, I have been able to outguess the
compiler with __forceinline__ but that is a different matter, not
related to the register keyword. With a half millions or so lines of
code, it is literally impossible for me to outguess the compiler with
register allocation.
But suffice it to say that the use of the register, inline, and
restrict keywords are nothing more or less than optimizations
techniques. Like all such techniques they are often used prematurely
and improperly. And like all such techniques, they can be used
properly and tested to verify that they do indeed achieve the desired
optimization.
For commercial compilers designed for large systems, I would be very
annoyed at any compiler that did not ignore the register keyword
completely. For embedded systems, you probably know a lot better than
I do.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Oct 16 '06 #29
Keith Thompson posted:
The "as if" rule doesn't really apply here. Despite the spelling of
the keyword, "register" doesn't tell the compiler to store the
object in a register.

C99 6.7.1:

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.

By that explanation, I would use register _all_ the time. I mean -- who
doesn't want their access to be as fast as possible?

--

Frederick Gotham
Oct 16 '06 #30
Frederick Gotham <fg*******@SPAM.comwrites:
Keith Thompson posted:
>The "as if" rule doesn't really apply here. Despite the spelling of
the keyword, "register" doesn't tell the compiler to store the
object in a register.

C99 6.7.1:

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.


By that explanation, I would use register _all_ the time. I mean -- who
doesn't want their access to be as fast as possible?
Fortunately you would be aware of C, how it came about and how certain
constructs are there for the wily programmer to try and maximise
compiler hints. And that there are limited registers available depending
on the target processor.
--
Oct 16 '06 #31

Frederick Gotham wrote:
Keith Thompson posted:
The "as if" rule doesn't really apply here. Despite the spelling of
the keyword, "register" doesn't tell the compiler to store the
object in a register.

C99 6.7.1:

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.


By that explanation, I would use register _all_ the time. I mean -- who
doesn't want their access to be as fast as possible?
When that access to something that does not need it prevents it from
happening to something that does need it.

If you have argc in main declared as a register, and the compiler
honors your request, and you have a one register machine, then the
nested inner loop array address won't get one.

I guess that 99% of register requests I see in source code (if honored)
would make programs slower. Even with the intelligent ones (e.g. an
address stride in a nested loop) the compiler is going to know if the
request is optimal[1].

[1] Apparently not, with embedded compilers. So caveat emptor. I
further guess that unless you are Jack Klein or some other really,
really smart guy, you still won't outguess even a badly designed
compiler.
--

Frederick Gotham
Oct 16 '06 #32
Kenneth Brody wrote:
pete wrote:
>>Snis Pilbor wrote:

>>>is unwise for any programmer to ever use the "register"
keyword if they want their code to run smoothly on all
mplementations

The register keyword tells the compiler
that you think that you know more about optimization
than the compiler does.


Compilers have gotten smarter over the years in terms of
optimization, while the human programmers haven't improved
that much. (Okay, the programmers writing the compiler
optimizers have learned more about optimizations, and in
doing so have made the compilers "smarter", while those
who use the compilers haven't improved siginificantly in
the area of optimization techniques.)
It's not merely that fancier optimization techniques have
been invented, but also that the machines running the compilers
are bigger and faster. It was once out of the question for the
compiler to trace out all the execution paths and discover when
a variable had reached the end of its "useful" lifetime -- there
simply wasn't enough memory to hold the graph, nor CPU cycles to
conduct searches in it. The increases in speed, size, and power
benefit the compilers just as they benefit the applications, and
techniques that were once infeasible are now routine.

--
Eric Sosman
es*****@acm-dot-org.invalid
Oct 17 '06 #33
dc*****@connx.com wrote:
Jack Klein wrote:
>>On Sun, 15 Oct 2006 04:49:24 GMT, Keith Thompson <ks***@mib.orgwrote
in comp.lang.c:
>>>Jack Klein <ja*******@spamcop.netwrites:
On 13 Oct 2006 17:07:04 -0700, dc*****@connx.com wrote in comp.lang.c:
>For the past ten years, the register keyword has been useless anyway.

Interesting assertion. Can you point to any measured test data to
back it up?

Do you have any measured test data to refute it?

Yes, for a wide variety of embedded compilers and for some PC based
ones, for specific situations. Going into detail would be off-topic
here.

I expect that my experience is different because I program large
systems (typically hundreds of thousands to millions of lines of code).

Register allocation is provably NP-hard, and is solved by very compute
intensive algorithms like graph coloring (though linear scan looks
promising for some situations):
I think this is missing the point. The problem is not hand allocating
registers for all million line of code, but rather let the compiler do a
good job for everything except where the programmer determines that

1) register allocation makes a significant difference
2) he can improve on the default allocation by specifying register
allocation of certain variables.

In C the programmer can specify where he wants specific allocation by
using the register keyword and allow default allocation everywhere else
by not specifying register.

This is similar to doing a good printed circuit board layout -- let the
autorouter do high 90s% of the work and allow the human to tweak the
routing where needed, if needed. The best result is a synergy between
man and machine.
For a large software system, no human on earth has the ability to
out-think the compiler when it comes to register allocation.
Man or machine is a false dichotomy. The best result is achieved by
using both in an intelligent way.

Part of the problem is the compiler not knowing the optimization
criteria. A compiler may be great at optimizing overall, but I may need
the minimum execution time between an interrupt and writing a servo
control. The rest of the code may be much less critical in terms of
timing. It may be better for that application to allocate 50% of the
registers to optimizing 10 lines of code in the critical path.
Allocating the variables for the critical path code is probably the
solution and yes, it needs to be verified.
On the other, other hand, embedded compilers may be primitive in their
ability to optimize register allocation and the embedded software
systems tend to be very small so in such a circumstance it may be
possible to do better than the compiler.
Unfortunately, that is often true. It seems ironic that usually more
effort is applied to optimizing targets with lots of resources and not
those with minimal resources. :-( Some low-end targeted compilers are
much better than others.
On rare circumstances, when
measurements indicated a problem, I have been able to outguess the
compiler with __forceinline__ but that is a different matter, not
related to the register keyword.
Actually I would consider it similar to the use of register. You are
saying "I need speed right here!" to the compiler for your particular
application.
With a half millions or so lines of
code, it is literally impossible for me to outguess the compiler with
register allocation.
And you don't need to do it for all lines, only the critical ones, just
the way you specified selective inlining. ;-)
For commercial compilers designed for large systems, I would be very
annoyed at any compiler that did not ignore the register keyword
completely.
"My code is good, compiler, except for use of 'register', in which case
you should assume that I am babbling nonsense". I recommend a
compile-time option to cater to that certain class of programmer.

--
Thad
Oct 18 '06 #34

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Joona I Palaste | last post by:
Consider this C program. #include <stdio.h> int main(void) { printf;("Hello world!\n"); return 0; } When we take into account the "as-if" rule, does this mean that the implementation is...
145
by: Sidney Cadot | last post by:
Hi all, In a discussion with Tak-Shing Chan the question came up whether the as-if rule can cover I/O functions. Basically, he maintains it can, and I think it doesn't. Consider two...
5
by: Hayato Iriumi | last post by:
When converting a type to another using CType and if the type conversion fails, it throw an exception. However, in C#, there is a keyword "as" which only makes the variable Nothing (null) without...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.