Teensy RAM Usage

Citabria

Active member
Not a bug report probably, but I'm curious about Teensy RAM ("dynamic memory") usage in Teensyduino.

When I compile the Blink example for the Arduino Mega 2560 under Arduino 1.8.8 and Teensyduino 1.45, I get this memory usage:
Sketch uses 1472 bytes (0%) of program storage space. Maximum is 253952 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 8183 bytes for local variables. Maximum is 8192 bytes.

When I compile the same example for Teensy 3.2, optimized for Smallest Code with LTO, I get this:
Sketch uses 6412 bytes (2%) of program storage space. Maximum is 262144 bytes.
Global variables use 2404 bytes (3%) of dynamic memory, leaving 63132 bytes for local variables. Maximum is 65536 bytes.

Why the huge difference in dynamic memory? What are those extra 2395 bytes doing? Run-time stack or something?

Is there a better way to write source code to reduce the RAM usage?
 
There are lots of differences between ARM Teensy and AVR Mega that lead to that. perhaps the biggest is Teensy has on chip full USB hardware and needs code and RAM for that - where the Mega just uses a Serial UART to pass of to an external processor to do all the USB work. Doing a Teensy verify with USB Type 'No USB' will show what that adds up to. That explains some of the extra code and RAM usage - but leads to more full featured USB abilities on Teensy. Currently there are a couple hundred pre-allocated bytes in the UART Serial buffers that seem to be missing from the 9 bytes reported by the Mega so that is artificially low unless that is disabled. The 32 bit ARM will add some bloat versus the 8 bit AVR as well. The AVR processor starts up ready to use its more limited features - the ARM starts up and needs initialization code to start and some RAM allocations to support more advanced interrupt and other features.

A 'new' sketch empty T_3.2 with USB Serial shows 8840 code 3436 RAM versus 'No USB' 4808 code and 1976 RAM compiled default Faster. That drops to 3044 and 896 'smallest' and goes to 2524 and 852 smallest w/LTO.
 
Thanks, that makes sense.

Thought I read here recently that constants go into RAM too unless you F() them. Shame. Not the case with AVR?
 
Thanks, that makes sense.

Thought I read here recently that constants go into RAM too unless you F() them. Shame. Not the case with AVR?

The AVR processors have a split address space, and the use determines which address space is used. I.e. if you are do a jump or call, it goes to the program address space. If you are doing normal loads/stores, it comes from the data address space. Address 0x34 in the text address space is not the same as 0x34 in the data address space. In classical computer terminology, this is called a Harvard architecture (after the Harvard Mark I). What the F() macro does on the AVR is it puts the constants in the text space, and then at runtime, copy the constant to the stack in the data space using special instructions to read data from the text area. When the function exits, the stack data will be discarded. There are a bunch of functions that specifically take a text address and do the special instructions, rather than forcing a large constant to be copied to the limited stack area.

The ARM processors have the data and text in the same address space, though usually the text is read-only. This type of machine is called a von Neumann architecture. If you use the const keyword, the compiler will put the value into the text area, and it will be read-only. If you don't use const it will go in the normal read/write SRAM area.
 
const is fine for named constants, but what about literal constants? Can't find the post now but thought Paul said they use RAM by default.
 
teensy and many arm mcus also have more c++ libraries and functionality supported in the core, which avr lacks mostly, but for dynamic you can get rid of the F() arduino style and just use const on teensy
 
Last edited:
Back
Top