global/static variables & loops

R

Rob Janecek

Hello,
In some coding advice I saw on the internet, we are urged to "avoid
referring to global or static variables inside the tightest loops".

I also read (elsewhere) that access time to global/static and
automatic variables can be different on different hardware
(i.e., automatic variables cannot always be counted on being
faster).

What is then the justification for the above quote? Could it be
that the compiler might avoid using registers for global/static
variables? But then why could it not just copy the variable to a
register and restore it's value after the loop's over (assuming,
of course, that there are no function calls or other side
effects in that tight loop)? I can see a problem with multi-
threading but is this not a special case that could be treated
separately by the compiler only when it arises?

[I have no problem following the advice, I'm just curious why it
is true...]
 
M

Malcolm McLean

In some coding advice I saw on the internet, we are urged to "avoid
referring to global or static variables inside the tightest loops".

What is then the justification for the above quote?
Reading and writing to main memory is now slow in comparison to
arithemtical operations with registers.

A global is maybe less likely to be in the cache or optimised away in
a register than an automatic scope variable.

But the advice isn't much use, really. If you need to step through a
large global array in an inner loop, it's unlikely that you can
rewrite the code to remove this requirement.
 
S

Stefan Ram

Rob Janecek said:
[I have no problem following the advice, I'm just curious why it
is true...]

The advice is to only optimize, /when/ needed,
and then to use a profiler to find the places, /where/ needed.
 
S

Stefan Ram

Rob Janecek said:
[I have no problem following the advice, I'm just curious why it
is true...]
The advice is to only optimize, /when/ needed,
and then to use a profiler to find the places, /where/ needed.

And to be aware that any optimization is faster only
relative to the specific compilation and execution
environment it was developed for.
 
S

Stephen Sprunk

In some coding advice I saw on the internet, we are urged to "avoid
referring to global or static variables inside the tightest loops".

I also read (elsewhere) that access time to global/static and
automatic variables can be different on different hardware
(i.e., automatic variables cannot always be counted on being
faster).

The Standard makes no guarantees at all about performance, so you can't
really "count on" anything always being faster or slower.
What is then the justification for the above quote? Could it be
that the compiler might avoid using registers for global/static
variables? But then why could it not just copy the variable to a
register and restore it's value after the loop's over (assuming,
of course, that there are no function calls or other side
effects in that tight loop)? I can see a problem with multi-
threading but is this not a special case that could be treated
separately by the compiler only when it arises?

Those are possible optimizations that any given implementation may or
may not perform.

As a general rule, I avoid global variables in the first place because
they tend to lead to violations of encapsulation, which IMHO is far more
important in most cases than absolute performance. Focus on making your
code clear and correct; let the compiler worry about the low-level
stuff. It will almost certainly do a better job of it anyway, and most
performance problems are caused by using the wrong algorithm anyway;
doing the wrong thing slightly faster rarely helps enough to make it
worth the effort.
[I have no problem following the advice, I'm just curious why it
is true...]

Before following any such advice, you should determine if it is correct
_for your implementation_. And, before that, you should determine if
the performance difference, if any, actually matters _for your program_.

S
 
E

Eric Sosman

Hello,
In some coding advice I saw on the internet, we are urged to "avoid
referring to global or static variables inside the tightest loops".

Reasonable advice. I'd go a little further, and delete the
final four words. Global variables have a way of tying together
pieces of your program that you didn't realize were related, and
this effect increases as the program grows larger. It's no good
having modular code if you also have spaghetti data.

That said, I'd also point out that "avoid" is not absolute;
perhaps "prefer not" would capture the notion more aptly. For
example, it's hard to argue against the global variable in

printf ("Hello, world!\n");

(If you don't see the global variable, try using fprintf() instead.)
That's a sort of yardstick you might want to use: When you're thinking
of making some variable global, as yourself whether it's as "useful"
to the program at large as `stdout' is. If it is, there's probably
a pretty good case for making it global. But if, say, 30% of your
program has no use for the variable, maybe it's not useful enough
to merit globality.
I also read (elsewhere) that access time to global/static and
automatic variables can be different on different hardware
(i.e., automatic variables cannot always be counted on being
faster).

No specific usage X can always be counted on to be faster than
some other usage Y. Still, global variables are likely to be out
of reach for some optimizations. For example, in

for (i = 0; i < global; ++i)
foobar = func(i);

.... the compiler may need to assume that func() might change the
value of `global'. That would require re-fetching `global' at
each iteration, instead of fetching it once and parking it in a
(fast) CPU register. It's even worse if `i' is global ...
What is then the justification for the above quote? Could it be
that the compiler might avoid using registers for global/static
variables? But then why could it not just copy the variable to a
register and restore it's value after the loop's over (assuming,
of course, that there are no function calls or other side
effects in that tight loop)? I can see a problem with multi-
threading but is this not a special case that could be treated
separately by the compiler only when it arises?

See above. Without inspecting func(), whose source may be
separately compiled, can you *prove* that `global' retains the
same value throughout the loop?

Advice 1: Don't make a variable global unless there's a truly
excellent case for it.

Advice 2: Don't fret too much about micro-optimization; the
time saved by choosing a (possibly) faster construct is unlikely
to repay the time spent in the choosing.
 
S

Stefan Ram

Eric Sosman said:
Reasonable advice. I'd go a little further, and delete the
final four words. Global variables have a way of tying together
pieces of your program that you didn't realize were related, and
this effect increases as the program grows larger. It's no good
having modular code if you also have spaghetti data.

The funny thing is that it's hard to explain this in
beginner's classes, because there is one type of program
where global variables don't hurt: very small programs. And
very small programs are used in beginner's classes. Even the
infamous namespace directive »using namespace ::std;«
doesn't really hurt in a small example program for beginners.
printf ("Hello, world!\n");
(If you don't see the global variable, try using fprintf() instead.)

If you had intended to refer to »stdout«: It's really /not/
there! There is no such thing as an invisible variable in C.
The global identifier that I /do/ see there is »printf«.
That's a sort of yardstick you might want to use: When you're thinking
of making some variable global, as yourself whether it's as "useful"
to the program at large as `stdout' is. If it is, there's probably

»stdout«, like »printf« is not necessarily a variable.
»stdout« is (after inclusing of <stdio.h>) an expressions of
type »pointer to FILE« that points to the FILE object
associated with the standard output stream.
 
P

Philip Lantz

Stefan said:
If you had intended to refer to »stdout«: It's really /not/
there! There is no such thing as an invisible variable in C.

Would you say the same thing if he had instead used the example
putchar('\n');
?
 
S

Stefan Ram

Philip Lantz said:
Would you say the same thing if he had instead used the example
putchar('\n');
?

Yes.

Even if the putchar function is equivalent to putc with the
second argument stdout. But this requirement just defines
the semantics of putchar. It is contrafactual to say that
the /call/ »putchar("\n")« contained a »global variable«,
when such a variable is not there.

(Also, the implementation of putchar is not required to read
from »stdout«, it could, for example, forward to an
operating system call of an OS function that does not even
know that in C there is such a name »stdout«, but just writes
to »process channel 7« of that operating system, which
happens to be known as »standard output« in C. But this
point is not my main point, just an additional observation.)

For example, a rule might forbid to use the word »water«
in a country where this word is considered indecent. Now,
when someone writes »ocean«, did he use the word water?
 
N

Nick Keighley

I have no problem following the [don't access globals in inner loops
optimisation] advice, I'm just curious why it is true...

  The advice is to only optimize,                     /when/  needed,
  and then      to use a profiler to find the places, /where/ needed.

....but to avoid early pessimisation. That is don't write unnecessarily
poor code. Write clear straight forward code at the beginning. Then
apply Stefan's rules.

In this case it looks like a micro-optimisation to me so Stefan's
rules apply.

Oh, and why does your progranm have global variables in the first
place?
 
B

BartC

Eric Sosman said:
On 2/14/2012 2:56 PM, Rob Janecek wrote:
That said, I'd also point out that "avoid" is not absolute;
perhaps "prefer not" would capture the notion more aptly. For
example, it's hard to argue against the global variable in

printf ("Hello, world!\n");

That's not likely to be part of a 'tight' loop though. The advice seems to
be more encouraging the use of globals than otherwise.
No specific usage X can always be counted on to be faster than
some other usage Y.

No. But there might be the need to push an extra parameter for millions of
function calls, when all they want to do is access the same file-scope (or
project-scope) variable, which can be done for nothing.

And if they all need write-access to that variable, an extra level of
indirection is needed; avoiding a global access can well introduce overheads
that cannot be offset by potential optimisations. And that's just one
global...
 
K

Kaz Kylheku

That's not likely to be part of a 'tight' loop though. The advice seems to
be more encouraging the use of globals than otherwise.

Machine registers are globals, and they are used in tight loops.
 
B

BartC

Kaz Kylheku said:
Machine registers are globals, and they are used in tight loops.

For those used as accumulators and scratchpad registers, then they don't
really correspond to the way actual global variables are used.

For those spare registers dedicated to particular uses by an application,
that just reinforces my point that access to globals can be streamlined
across different functions; they're always there for instant access.
(Although I'd imagine that in C, such uses are mainly for local variables
not globals.)
 
M

Malcolm McLean

Machine registers are globals, and they are used in tight loops.
Global and local are language concepts. You could certainly produce a
language in which registers are globals, and in fact some dialects of
C do that. You can refer to a register directly by name. But in most
languages registers are not available as globals.
 
M

Malcolm McLean

To handle a global state maybe.
A lot of programs work on a model / view paradigm. The model consists
of the data which the user is wanting to manipulate. The user
interface then provides various ways of seeing that data and issuing
instructions to manipulate it.

It often makes sense to have the model as a global.
 
J

James Kuyper

A lot of programs work on a model / view paradigm. The model consists
of the data which the user is wanting to manipulate. The user
interface then provides various ways of seeing that data and issuing
instructions to manipulate it.

It often makes sense to have the model as a global.

Only if it never makes sense to have more than one instance of the model
manipulated by the same program. I've often written programs which only
manipulated a single model; but most, if not all, of those models were
things that there could have been two or more of in a single program.
When that's the case, it makes more sense to pass the model around
though pointer arguments.
 
A

August Karlstrom

The funny thing is that it's hard to explain this in
beginner's classes, because there is one type of program
where global variables don't hurt: very small programs.

I think it is more a question of static vs. non-static global variables.
As I see it, the only place for non-static global variables is in the
main translation unit (although it won't hurt to make them static there
too).


August
 
A

Anders Wegge Keller

Nick Keighley said:
Oh, and why does your progranm have global variables in the first
place?

Can you give an example of a non-trivial program, that has no global
state in any way?
 
J

James Kuyper

Can you give an example of a non-trivial program, that has no global
state in any way?

Most of the programs I'm responsible for were originally written by
other people, and they usually made a lot of use of global variables at
the time I became responsible for them. However, I've slowly been
removing those variables, and the only difficulty with doing so that
I've ever had was finding adequate justification for bothering to spend
the time needed to remove them.

The code I wrote entirely myself almost never uses globals, but I don't
know whether it would count as non-trivial for your purposes. However,
almost all of my code has to be linked to various libraries written by
other people, and those libraries often use globals, such as errno in
<errno.h>. errno isn't required to be a global, but it often is, so I
guess you're right - it all has some global state, even if there's no
real reason why global state is needed.
 

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,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top