15

For clarification: I know how evil globals are and when not to use them :)

  • Is there any performance penalty when accessing/setting a global variable vs. a local one in a compiled C++ program?
Dr. Acula
  • 449
  • 1
  • 5
  • 6
  • 5
    A better question would be "Why dos it matter?" When someone starts micro-optimizing details like this, it tells me that they have a performance problem and are looking for ways to fix it. If that's the case, *profile* and find the bottlenecks. Don't sweat this kind of stuff. It's not worth your time. – greyfade May 19 '10 at 17:55
  • 1
    Anyway, I think I've finally found the way to boost my rep without too much hassle: it's sufficient to ask a question with "performance" thrown in the middle and suddenly you get so many votes you don't know what to do with them! – Matthieu M. May 20 '10 at 06:22
  • 1
    "I know how evil globals are and when not to use them": there's never a good reason to use a global variable, only laziness. The only globals you should have are constants. – Matthieu M. May 20 '10 at 06:24

9 Answers9

21

That would depend entirely on your machine architecture. Global variables are accessed via a single known address, whereas local variables are typically accessed by indexing off an address register. The chances of the difference between the two being significant is extremely remote, but if you think it will be important, you should write a test for your target architecture and measure the difference.

  • Why does so much depend on my machine architecture :( That makes things hard to optimize – Dr. Acula May 19 '10 at 17:39
  • 1
    If you are looking to optimize your program you should be profiling it and finding the bottlenecks not guessing where the bottlenecks might be. Short of accessing your global often in a manner that completely trashes the cache you almost certainly aren't going to see anything related to this as a bottleneck. – Andrew Khosravian May 19 '10 at 18:09
  • 4
    @Dr. Acula Computers are real-world machines, not idealised concepts. If you need your code to run as fast as possible, you must address the various quirks of the real-world machine. Of course, 99.99% of the time you don't need your code to run as fast as possible, only fast enough - in which case you should not even think about optimisation, but leave things up to the compiler. –  May 19 '10 at 18:24
  • 1
    Delaying optimizations allows for you to spend more time on the critical ideals: correctness and robustness. Only spend time on performance with customers complain (including internal customers). Marketing groups may want more features added rather than improving the programs performance. – Thomas Matthews May 19 '10 at 18:51
  • Inside a tight loop you may get caching benefits using a local variable, the stack will usually be hot. Thats assuming a large and complex processor of course, DSP's, small embedded chippys etc won't have this issue... – Hayman May 20 '10 at 02:45
  • 1
    Actually, there is a very big chance that local variables will not be accessed _via_ a register, but will be stored _in_ a register. This means they'll be a whole lot faster (factor of 10) – MSalters May 20 '10 at 09:12
10

It depends but usually yes although it is a micro issue. Global variables should be reference-able from many contexts, which means that putting them into a register is not possible. While in the case of local variables, that is possible and preferable. In fact, the more narrower the scope the more the compiler has the opportunity to optimize access/modifying that variable.

Khaled Alshaya
  • 94,250
  • 39
  • 176
  • 234
  • 2
    Actually, you can put a global variable in a register in gcc: register unsigned long *ds asm("ebx"); but this is probably slower since you're starving your entire codebase of a register. – geocar May 19 '10 at 17:56
8

Local variables are probably "faster" in many cases, but I don't think the performance gain would be noticeable or outweigh the additional maintenance cost of having many global variables. Everything I list below either has a negligible cost or can easily be dwarfed by just about any other inefficiency in your program. I would consider these to be a perfect example of a micro-optimization.

Local variables are on the stack, which is more likely to be in the cache. This point is moot if your global variable is frequently used, since it will therefore also be in the cache.

Local variables are scoped to the function - therefore, the compiler can presume that they won't be changed by any other function calls. With a global, the compiler may be forced to reload the global value.

On some 64-bit machines, getting the address of a global variable is a two-step process - you must also add the 32-bit offset of the global to a 64-bit base address. Local variables can always be directly accessed off of the stack pointer.

Michael
  • 54,279
  • 5
  • 125
  • 144
5

Strictly speaking, no.

Some things to consider: Global variables increase the static size of your program in memory. If access to the variable needs to be synchronized, that would incur some performance overhead.

Adam Holmberg
  • 7,245
  • 3
  • 30
  • 53
5

There are a number of compiler optimisations that are possible with local variables but not with global variables, so in some cases you might see a difference in performance. I doubt that your global variable is being accessed in a performance-critical loop though (very bad design if it is !) so it's probably not going to be an issue.

Paul R
  • 208,748
  • 37
  • 389
  • 560
3

It's more of the way how you use data stored in your variables that matters performance wise then how you declare them. I'm not sure about the correct terminology here, but one can define two types of data access. Shared access (where you access same data from different parts of the code) and private data, where each part has its own data. By default global variables imply shared access and local imply private access. But both types of access can be achieved with both types of variables (i.e. local pointers pointing to the same chunk of memory, or global array where each part of code access different part of array).

Shared access has better caching, lower memory footprint, but is harder to optimize, especially in multi threaded environment. It is also bad for scaling especially with NUMA architecture..

Private access is easier to optimise and better for scaling. Problems with private access usually exist in situation where you have multiple copies of same data. The problems usually associated with these scenario's are higher memory footprint, synchronization between copies, worse caching etc.

Ivan
  • 1,735
  • 1
  • 17
  • 26
2

The answer is tied to the overall structure of the program.

For example, I just disassembled this, and in both cases the looping variable was moved into a register, after which there was no difference:

int n = 9;
int main()
{
    for (n = 0; n < 10; ++n)
        printf("%d", n);

    for (int r = 0; r < 10; ++r)
        printf("%d", r);

    return 0;
}

Just to be sure, I did similar things with classes and again saw no difference. But if the global is in a different compilation unit that might change.

egrunin
  • 24,650
  • 8
  • 50
  • 93
1

There is no performance penalty, either way, that you should be concerned about. In adition to what everyone else has said, you should also bear in mind the paging overhead. Local instance variables are fetched from the object structure which has likely (?) already been paged into cache memory). Global variables, on the other hand, may cause a different pattern of virtual memory paging.

Again, the performance is really not worth any consideration on your part.

Vagrant
  • 1,696
  • 12
  • 19
1

In addition to other answers, I would just point out that accessing a global variable in a multithreaded environment is likely to be more expensive because you need to ensure it is locked properly and the threads may wait in line to access it. With local variables it is not an issue.

Nemanja Trifunovic
  • 24,346
  • 3
  • 50
  • 88