Postby MicroController » Fri Sep 08, 2023 9:06 am
When a function gets inlined, its code is "copied" into the calling function. If the calling function is not ATTR_IRAM neither is any code inlined into it.
This usually isn't much of an issue since the caller isn't in IRAM anyway; but the caller's code may get bigger by the inlining, so more code may need to be fetched from flash.
Gcc decides if a function call gets inlined based, among other factors like optimization flags, on the size of the called function. Tiny/trivial ("one-line") functions have a higher likelihood of being inlined than bigger ones. Gcc's underlying performance cost calculation doesn't take into account IRAM or the (worst-case) cost of fetching code from flash; it kind-of does when optimizing for code size (-Os). You can leave the decision to gcc, especially as the result will automatically adapt to future code changes. If you don't want that, you can use __attribute__((noinline)).
Note though that the ESPs have an in-RAM cache for the flash memory. Code which runs frequently, or in a tight loop, will run directly from the cache at the same speed it would from IRAM. That said, actual performance benefits of IRAM functions may be minute to non-existing in many cases. The main reason to use IRAM code is for the code to be able to run when the cache is unavailable, specifically during writes (OTA, NVS,...) to the flash.