No I'm really serious.
I've just witnessed someone move variables local to a function up to global status, with the commit message "Relieve the stack".
Is there really some rationale towards doing this sort of thing?
No I'm really serious.
I've just witnessed someone move variables local to a function up to global status, with the commit message "Relieve the stack".
Is there really some rationale towards doing this sort of thing?
First, putting variables in global variables doesn't improve CPU usage directly. Stack initialization is generally a single add/subtract at function entry/exit, independent of stack frame size.
However, if the function requires a very large working set, it's better to put it in something other than stack; the stack's size is usually rather limited. The usual choice is the heap; however this does take time to allocate and free, and so if you're going to be calling the function frequently it can be expensive. It's also a problem on embedded systems, where they may not have a proper heap implementation.
So if heap is a problem, globals can be a solution. However, they have their own downsides - in particular, you don't want to have multiple threads messing with the global data at the same time, nor can you recurse through this function without taking a lot of care, or the recursed bits may corrupt the earlier calls to the function.
So it's a technique which, in some cases, can be helpful. I wouldn't recommend using it as a first choice however, because of threading issues.
Also, for what it's worth, you can get the same memory effects with static
variables. I would recommend using these instead, as otherwise you'll end up polluting the global namespace.
There is this myth around that global variables make your program "faster". That's crap.
However, if you use a large static array, you may want not to put it on the stack to prevent the risk of a stack overflow. The stack memory is considerably small compared to overall logical memory space.
In a well-designed program that is larger than 100 LOC you may want to use other ways of allocation for your huge data: putting it into an object (std::vector etc.) or using malloc/free, new/delete.
If the variables were declared static
there is probably no difference.
If they were not, then there will be less stack pushing and popping, but the behaviour of the program might change.
Using global variables instead of function parameters will reduce the needed stack space for calling the function. That is probably where that comment originated from. But as all global variables live throughout the whole duration of the program, the overall RAM consumption of the program will be higher.
This is no myth, many kinds of systems have sluggish stacks. The effect will far less notable on a PC or other such high-end 32/64 bit CPUs (nothing in the original post indicates PC though).
Global variables instead of parameters is usually very bad practice however, as it leads to spaghetti. To avoid that, such variables should be declared static.
The best practice to reduce stack space when calling a function is inlining, if you have that option.
If you're worried about stack overflow in recursion, and global variables could solve your problem, there's a much better solution: put all variables in a struct
in the outermost wrapper function for your recursion, and pass a pointer to that struct to the actual recursive function. This approach gives you all the benefits of global variables, and none of the disadvantages.
Also note that on modern systems with position-independent code and shared libraries, accessing global variables is often significantly slower than accessing local variables or accessing members of a struct indirectly through a single pointer, due to the costs of GOT-relative addressing and similar.
Don't use global variables unless you really need to have global state, and even then, try to eliminate it. Never introduce global variables as an "optimization".
Is there really some rationale towards doing this sort of thing?
No.