0

I am writing in C++ for a low-spec device (~3MB RAM, ~70MHz CPU) and I am wondering which will run more efficiently (And by how much). This is a simplified segment of code that will run 120-600 times a second:

void checkCollisions(int x, int y)
{
    int p1x = x, p1y = y+2;
    int p2x = x, p2y = y+3;
    int p3x = x+3, p3y = y+3;
    // And so on...

    if (wallAt(p1x-1, p1y) || wallAt(p2x-1, p2y))
        setCollision(LEFT, true);
    if (wallAt(p1x, p1y) || wallAt(p4x, p4y) || wallAt(p5x, p5y))
        inGround = true;
    else
        inGround = false;
    // And so on...
}

Or replacing the integers with their definitions:

void checkCollisionsAlt(int x, int y)
{
    if (wallAt(x-1, y+2) || wallAt(x-1, y+3))
        setCollision(LEFT, true);
    if (wallAt(x, y+2) || wallAt(x+3, y) || wallAt(x+2, y))
        inGround = true;
    else
        inGround = false;
    // And so on...
}

Here's a diagram of the example:

Example Diagram

The first one is more understandable, but I would expect uses more memory. How much of a difference does it make?

Matthew D. Scholefield
  • 2,977
  • 3
  • 31
  • 42

3 Answers3

1

A few points to think about:

  1. If the full version also doesn't have any recursion, you can worry less about the variables(p1x etc.) on the stack.
  2. Stack-consumption is ephemeral and shouldn't hit you unless you have pathological code, such as deep recursion with each frame being heavy.
  3. Recursion usually is a bad idea with a tight memory budget.
  4. The fact that you have them as explicitly named variables, does not mean they will be so at the execution time.
  5. Any decent compiler is likely to recognize the life-time of the variables and push them to registers. Please verify this with the compiler optimization level that you are currently using and consider bumping it up, if needed.

Also, what is the expected range of these values of p1x etc. Why not use short int?

Ephemeral nature of the stack memory growth means that your peak heap memory is not impacted. Stack can grow and shrink and depending on the lay out and amount budgeted for stack, you might not have to worry about this at all.

Note: Any and ALL heap allocations need to be carefully vetted. Try implementing a custom allocator, rather than incurring the standard malloc() chunk overheads. Of course, you didn't bring up the heap in the question, but, just a thing to keep in mind.

KalyanS
  • 527
  • 3
  • 8
1

What will make your code faster if the compiler worked as you want is to put all your variable into registers. I think that any modern compiler will understand from itself that your 2 code versions are the same and will give the same - or very similar - output. It will try to utilize the core register in both cases and will use the memory - stack in this case - only if no sufficient number of registers is available. If the compiler give you the option to keep the intermediate assembly files do that and you can make a deep understand of your codes and the performance. Remember that the low memory access - registers used instead - will enhance your code performance.

0

If the machine runs at 70 MHz, that means it has 117,000 cycles every 600th of a second.

If instructions take an average of 10 cycles each, it can execute 11,700 instructions in a 600th of a second.

As I look at your code, either one, I'm guesstimating about 100 instructions to execute it. 100/11,700 = roughly 1% of time spent running this code.

You could step through it at the assembly language level to see how many instructions it takes, but it probably won't make much difference.

I suspect you have bigger fish to fry elsewhere.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
  • There are close to 100 other small situations slightly similar so I think it best to change how I code so when writing things like this I choose the best one. For this reason, the question remains significant despite this individual scenario not taking up substantial CPU time. – Matthew D. Scholefield May 03 '15 at 00:40
  • 2
    @RandomPerson323: OK, then let me give you some take-it-to-the-bank, can't-lose additional advice, which you can accept or not. This is not something you do in advance. Get the code running, and use [*this technique*](http://stackoverflow.com/a/378024/23771). It will tell you exactly what you should be worried about, which is almost certain to be something other than what you are concerned about now. – Mike Dunlavey May 03 '15 at 00:45