3

Say that I have the following situation:

void myFunc()
{
    int x;
    //Do something with x
}

"x" is placed on the stack which is no doubt fast.

Now, "myFunc" is called very frequently, lets say 10 times per second. Is it plausible to do something like this:

int x;
void myFunc()
{
    //Do something with x
}

so that x gets allocated in the applications data segment. but it is allocated only once. Since "myFunc" is called so frequently, does the second approach deliver any performance benefits?

Nitkov
  • 159
  • 1
  • 7
  • In your example `x` is stored in the applications data segment, not on the heap. – Gábor Angyal Feb 06 '15 at 08:58
  • 1
    possible duplicate of [Why is Global State so Evil?](http://programmers.stackexchange.com/questions/148108/why-is-global-state-so-evil) – gnat Feb 06 '15 at 08:59
  • think of what could happen when you or someone else adds `void otherFunc() { /* do something weird with x */ }` – gnat Feb 06 '15 at 09:01
  • 2
    @gnat The question you linked focuses on design aspects of global variables. What I wanted to know more about was the performance aspect. I could not find such an answer. If you are aware of one, please do mark it. I will try to place more weight on "performance" in my question. – Nitkov Feb 06 '15 at 09:03
  • @gnat It is definietly a bad design decision to do this. But the question is about performace, so I do not beleive that it is a duplicate of what you linked. – Gábor Angyal Feb 06 '15 at 09:04
  • @GaborAngyal Any good links on that? But the performance aspect of my question still stands. – Nitkov Feb 06 '15 at 09:04
  • @Solver I think ratchet freak's answer is good. – Gábor Angyal Feb 06 '15 at 09:06
  • @GáborAngyal Edited the "heap vs data segment" per your comment. – Nitkov Feb 06 '15 at 09:08
  • @GáborAngyal performance aspects are _thoroughly_ covered over here, eg in [When should I care about performance?](http://programmers.stackexchange.com/a/197/31260), [Clean readable code vs fast hard to read code. When to cross the line?](http://programmers.stackexchange.com/a/89623/31260), [Is micro-optimisation important when coding?](http://programmers.stackexchange.com/q/99445/31260) and in _multiple_ other questions linked to these – gnat Feb 06 '15 at 09:14
  • @GáborAngyal I feel that we are in a misunderstanding. Your links talk about "is it smart to optimise in this case?", "This code is pretty but slow, should I make it ugly and fast?". In all those cases the OP knows if his code is fast or slow and looking for advice on whether to sacrifice readability for speed. My question is rather simple - performance-wise, are there any benefits in global variables when the function is called very frequently? In short (and this is maybe how I should have stated my question), is method number two faster for a sufficiently high call frequency? – Nitkov Feb 06 '15 at 10:02
  • @Solver I think you meant to address gnat – Gábor Angyal Feb 06 '15 at 10:11
  • @gnat sorry about that Gabor. Yes my last comment was for gnat – Nitkov Feb 06 '15 at 10:13
  • 1
    your explanation makes me feel more and more that this is [XY-problem](http://meta.stackexchange.com/a/66378/165773). It's like looking for blanket justification to get into extremely dangerous code when things should indeed work opposite - jou just don't get there unless you have a hard proof that this is the only option. And no, saved processor ticks don't qualify. In one of past projects we were counting every tick, including even being forced to use macros to save on function calls, and in there, it was simply _forbidden_ to declare variables that way, because that's way too dangerous – gnat Feb 06 '15 at 10:23
  • ...it's a bit like asking "I want to write code open to [SQL injection](http://stackoverflow.com/tags/sql-injection/info), how do I go about doing this?" – gnat Feb 06 '15 at 10:46
  • @gnat I will most definitely not use the second approach, so it can't be the XY-problem. All of us are aware that the second solution is a no-go in almost every case. But I still don't see why there can't be an answer if the code can theoretically be better in performance. I simply asked the question in order to better understand the performance aspect of the situation in question. No offense but you seem to be a bit stuck on "that is bad programming" and you seem to be ignoring the theoretical nature of my question. For reasons unknown. – Nitkov Feb 06 '15 at 11:13
  • @gnat Say that I am making website that someone will use to practice SQL injection attacks (to learn by example and therefore learn how to protect against said attacks). Therefore I want to make a SQL injection prone website. Is the question "How to make my website open to SQL injection?" not valid in that case? But we are getting extremely off-topic and need to put a stop to this ASAP. – Nitkov Feb 06 '15 at 11:18
  • 1
    These days, 10x/second may not qualify as 'frequent' :-) – Dan Pichelman Feb 06 '15 at 15:21
  • [*Use the disassembler, Solver*](http://en.wikipedia.org/wiki/Disassembler). And [*do yourself an intro*](http://en.wikipedia.org/wiki/Computer_architecture). – rwong Feb 07 '15 at 23:32
  • On some earlier times you could write statements like `register int i;` to advise the compiler to keep this variable in registers. I wonder if today's C-compilers still do this. – ott-- Feb 08 '15 at 00:57

2 Answers2

16

Allocating a variable on the stack and deallocating it is a simple addition and subtraction of the stack pointer. Given that it happens anyway when entering a function means that local variables are so cheap that trying to optimize them to anything else will generally incur more cost.

Putting it in the data segment will incur a cache cost, the stack will usually be in cache.

The biggest disadvantage is that you lose reentrant properties. Meaning that recursion won't work and that it's not thread-safe.

The other big disadvantage is that letting the variable escape scope is that the optimizer can't make it a register-only variable, which never reaches RAM to begin with.

ratchet freak
  • 25,706
  • 2
  • 62
  • 97
  • 9
    Just to make the conclusion more obvious: Promoting a local variable to a global is likely to make the code **slower**, not faster. – Sebastian Redl Feb 06 '15 at 11:11
3

It also depends on the architecture. In ARM the first few locals are stored in registers only. As long as you do not call any other functions then these will never go on to the stack.

You need to go the opposite direction. Rather than using globals you should start by limiting the scope if the variables as much as possible. Not only is this good coding practice but it also helps the compiler to better optimize your code. You should compile with maximum speed optimization then look at the generated assembler code. Even better is to step through this code if your IDE will show you the ASM at the same time as the C code. You will be surprised at what the compiler can do. See here for a good discussion: https://stackoverflow.com/questions/15180309/local-variable-location-in-memory

Only after you have good readable code that had been optimized by the compiler should you start looking at custom hand coded optimizations. Normally this is only needed for special real-time applications with very strict time constraints.

Tereus Scott
  • 296
  • 1
  • 4