Optimize static and stack memory

Previously, we explained tool-assisted techniques for optimizing heap memory, and now we will describe some tips for optimizing static and stack memory:

Code

In embedded systems, it is particularly important to optimize the size of a binary, not only because it takes RAM memory, but also because it uses expensive flash memory. Below are some tips you can use to optimize the size of an executable:

  • Ensure that the binary is compiled without debug information when you measure it. Debug data is the largest contributor to the size of the executable, if it is enabled.
  • Strip the binary to remove any remaining symbol information
  • Remove any unused functions
  • Find and eliminate code clones
  • Try compiler performance optimization flags, such as -O and -O2
    There is no guarantee that code would be smaller; it can actually be larger in some cases.
  • Do not use the char type to perform int arithmetics, particularly when it is a local variable. Converting to int and back (code inserted by the compiler) affects performance and code size (particularly on ARM).
  • Bit fields are also very expensive in arithmetics on all platforms; it is better to use bit arithmetics explicitly to avoid hidden costs of conversions.

Data

  • Inspect global arrays that significantly contribute to static memory consumption. In some cases, it may be better to use the heap, particularly when this object is not used through the entire process life cycle.
  • Find and remove unused global variables
  • Be aware of structure padding; consider rearranging fields to achieve smaller structure size.

Stack

In some cases, it is worth the effort to optimize the stack, particularly when the application has some frequent picks of stack activity (meaning that a huge stack segment would be constantly mapped to physical memory). You can watch the Memory Information view for stack allocation and inspect code that uses the stack heavily. This usually occurs in two cases: recursive calls (which should be avoided in embedded systems), and heavy usage of local variables (keeping arrays on the stack).

Tasks such as finding unused objects, structures that are not optimal, and code clones, are not automated in the QNX Momentics IDE. You can search for static analysis tools with given keywords to find an appropriate tool for this task.