global/static variables & loops

Discussion in 'C Programming' started by Rob Janecek, Feb 14, 2012.

  1. Rob Janecek

    Rob Janecek Guest

    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...]
    Rob Janecek, Feb 14, 2012
    #1
    1. Advertising

  2. On Feb 14, 7:56 pm, Rob Janecek <> wrote:
    >
    > 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.
    --
    Visit my website
    http://www.malcolmmclean.site11.com/www
    Malcolm McLean, Feb 14, 2012
    #2
    1. Advertising

  3. Rob Janecek

    Stefan Ram Guest

    Rob Janecek <> writes:
    >[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.
    Stefan Ram, Feb 14, 2012
    #3
  4. Rob Janecek

    Stefan Ram Guest

    -berlin.de (Stefan Ram) writes:
    >Rob Janecek <> writes:
    >>[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.
    Stefan Ram, Feb 14, 2012
    #4
  5. On 14-Feb-12 13:56, Rob Janecek wrote:
    > 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

    --
    Stephen Sprunk "God does not play dice." --Albert Einstein
    CCIE #3723 "God is an inveterate gambler, and He throws the
    K5SSS dice at every possible opportunity." --Stephen Hawking
    Stephen Sprunk, Feb 14, 2012
    #5
  6. Rob Janecek

    Eric Sosman Guest

    On 2/14/2012 2:56 PM, Rob Janecek wrote:
    > 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.

    --
    Eric Sosman
    d
    Eric Sosman, Feb 15, 2012
    #6
  7. Rob Janecek

    Stefan Ram Guest

    Eric Sosman <> writes:
    > 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.
    Stefan Ram, Feb 15, 2012
    #7
  8. Rob Janecek

    Philip Lantz Guest

    Stefan Ram wrote:

    > Eric Sosman <> writes:
    > >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.


    Would you say the same thing if he had instead used the example
    putchar('\n');
    ?
    Philip Lantz, Feb 15, 2012
    #8
  9. Rob Janecek

    Stefan Ram Guest

    Philip Lantz <> writes:
    >Stefan Ram wrote:
    >>Eric Sosman <> writes:
    >>>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.

    >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?
    Stefan Ram, Feb 15, 2012
    #9
  10. On Feb 14, 8:46 pm, -berlin.de (Stefan Ram) wrote:
    > Rob Janecek <> writes:


    > >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?
    Nick Keighley, Feb 15, 2012
    #10
  11. Rob Janecek

    BartC Guest

    "Eric Sosman" <> wrote in message
    news:jhf24h$kmr$...
    > On 2/14/2012 2:56 PM, Rob Janecek wrote:


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


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

    >> I also read (elsewhere) that access time to global/static and
    >> automatic variables can be different on different hardware


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

    --
    Bartc
    BartC, Feb 15, 2012
    #11
  12. Rob Janecek

    Kaz Kylheku Guest

    On 2012-02-15, BartC <> wrote:
    >
    >
    > "Eric Sosman" <> wrote in message
    > news:jhf24h$kmr$...
    >> On 2/14/2012 2:56 PM, Rob Janecek wrote:

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

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


    Machine registers are globals, and they are used in tight loops.
    Kaz Kylheku, Feb 15, 2012
    #12
  13. Rob Janecek

    BartC Guest

    "Kaz Kylheku" <> wrote in message
    news:...
    > On 2012-02-15, BartC <> wrote:
    >> "Eric Sosman" <> wrote in message
    >> news:jhf24h$kmr$...
    >>> On 2/14/2012 2:56 PM, Rob Janecek wrote:

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

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

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

    --
    Bartc
    BartC, Feb 15, 2012
    #13
  14. On 2012-02-15 10:23, Nick Keighley wrote:
    > Oh, and why does your progranm have global variables in the first
    > place?


    To handle a global state maybe.


    August
    August Karlstrom, Feb 15, 2012
    #14
  15. On Feb 15, 11:42 am, Kaz Kylheku <> wrote:
    >
    > 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.

    --
    Malcolm's website. Free games, programming material, and even some
    poems.
    http://www.malcolmmclean.site11.com/www
    Malcolm McLean, Feb 15, 2012
    #15
  16. On Feb 15, 1:03 pm, August Karlstrom <> wrote:
    > On 2012-02-15 10:23, Nick Keighley wrote:
    >
    > > Oh, and why does your progranm have global variables in the first
    > > place?

    >
    > 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.
    --
    MiniBasic - how to write a script interpreter
    http://www.malcolmmclean.site11.com/www
    Malcolm McLean, Feb 15, 2012
    #16
  17. Rob Janecek

    James Kuyper Guest

    On 02/15/2012 08:20 AM, Malcolm McLean wrote:
    > On Feb 15, 1:03�pm, August Karlstrom <> wrote:
    >> On 2012-02-15 10:23, Nick Keighley wrote:
    >>
    >>> Oh, and why does your progranm have global variables in the first
    >>> place?

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


    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.
    --
    James Kuyper
    James Kuyper, Feb 15, 2012
    #17
  18. On 2012-02-15 02:51, Stefan Ram wrote:
    > 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
    August Karlstrom, Feb 15, 2012
    #18
  19. Nick Keighley <> writes:

    > 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?

    --
    /Wegge

    Leder efter redundant peering af dk.*,linux.debian.*
    Anders Wegge Keller, Feb 15, 2012
    #19
  20. Rob Janecek

    James Kuyper Guest

    On 02/15/2012 09:55 AM, Anders Wegge Keller wrote:
    > Nick Keighley <> writes:
    >
    >> 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?


    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.
    --
    James Kuyper
    James Kuyper, Feb 15, 2012
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Wayne
    Replies:
    2
    Views:
    469
    Wayne
    Nov 11, 2003
  2. Marcin Vorbrodt

    Global static variable vs static method

    Marcin Vorbrodt, Sep 5, 2003, in forum: C++
    Replies:
    3
    Views:
    5,420
    Denis Perelyubskiy
    Sep 5, 2003
  3. jubelbrus
    Replies:
    5
    Views:
    616
    JohnQ
    Jul 20, 2007
  4. Mark
    Replies:
    2
    Views:
    421
    Jim Langston
    Oct 16, 2007
  5. Me
    Replies:
    2
    Views:
    244
Loading...

Share This Page