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?
For clarification: I know how evil globals are and when not to use them :)
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.
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.
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.
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.
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.
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.
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.
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.
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.