2

I'm currently working on a project on an Arduino that should run for multiple years without interruption. To do this, I've attempted to avoid constructors, deconstructors and general dynamic variable allocation all together, as to avoid memory leaks and other ways of running out of memory.

This project has a couple of very large arrays. I've had a couple instances where after changing one #define my code would upload, but hang within seconds. Changing these arrays to static instead gave me errors while uploading, indicating there was not enough memory available. Hence I went down this route.

My question is about the performance of this approach. Right now, I've got a function that has a body as such:

  uint16_t total = 0;
  uint8_t count = 0;
  for (int8_t i = AMOUNT_OF_MEASUREMENTS_FOR_AVERAGE; i>=0;--i){
    if (measurementsHigh[i] == 255){
      continue;
    }
    count++;
    total+=measurementsHigh[i];
  }
  if (count == 0){
    return 0;
  }
  return total/count;

This calculates the average of all values in measurementsHigh. It however, also allocates four bytes on the stack. I was planning on rewriting this, so that the variables i, count and total are declared in the class as being static, and so take these 4 bytes into consideration while uploading.

My question is absolutely not about whether this is considered useful. To one it might seem to only add complexity and make the program less readable, to the other it would seem wise in the context of embedded programming. That could lead to discussions I would not like to provoke.

Instead, my question is what this does performance-wise. I use this code-block multiple times, and can use the same variables from a couple points of my code. Is this faster, slower, or does it completely not matter speed-wise? Does it improve the stability of my program to avoid using the stack? (I know, with proper use one could not create a memory leak on the stack, but still... aforementioned huge arrays...) Are there other ways to improve the stability of this code, which I have overlooked?

  • You could consider having your own allocators. – Basile Starynkevitch Aug 2 '16 at 12:02
  • 2
    you disassembled the code and confirmed it is really using the stack here? an optimizer and number of registers in an AVR, it should be using registers for this and not actually burn stack. But it depends on your AVR, compiler, etc. – old_timer Aug 2 '16 at 17:00
  • When/where do you gather this data, you could be collecting these values when you are gathering this data and not in this separate function, it might use more stack in that code, but you wont end up going across the array multiple times, repeating all of those memory accesses. If you are trying to improve performance by focusing only on this function. there is not much more you can do. you might try indexing from 0 to n-1 rather than n-1 to zero there may be some hardware buffering that comes into effect. – old_timer Aug 2 '16 at 17:02
  • accurately timing the code and examining the disassembly and trying things like 0 to n-1 instead of n-1 to zero. Are how you would tune this code/function for performance. I doubt the AVR has any caching and doubt it has a big fetch line so I doubt the alignment of the function/loop and/or alignment of the data would affect performance (can make a huge difference in systems with caches and that fetch many instructions per transfer) – old_timer Aug 2 '16 at 17:04
1

Using the same variables from a couple of points in your code may work if you are very careful but also invites opportunity for bugs that are hard to find which does not help the stability of your program.

As to whether it executes faster depends on the microcontroller. Some microcontrollers have instructions that allow addressing relative to the stack pointer which may be faster (if you leave the variables on the stack). You would have to review the assembly listing to see what instructions are being used in both cases. The loop is relatively small, 256 iterations at most, so any difference would likely be minimal.

Leaving the variables on the stack would also free up those 4 bytes for use elsewhere in your program which sounds like it would be helpful since you are already running out of RAM. You may also want to consider reviewing the stack and heap sizes. Maybe you can reduce the RAM allocated to either or both of these spaces to free up RAM. If you are not using any dynamic memory allocation, you can set your heap size to zero if you have not already.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.