mschnell
Posts: 70
Joined: Wed Jul 28, 2021 10:33 am
Location: Krefeld, Germany

const array in flash

Sat Sep 18, 2021 11:06 am

Without much thinking, I defined a big const array that is accessed by the software in a random way.
Later I wondered if that should clutter the flash cash. I took a look at the map file and found that regarding the placement, the compiler ignores the "const" and handles it as if it was a preloaded var in RAM.
That is exactly what I desired.
But OTOH, there might be instances when this is not desirable. E.g. when a huge array is used only sporadically and should reside in flash, or when moving the project into RAM on start, whoch wpould result of two copies of such an array in RAM.
Are there special options for such ?
-Michael

dshadoff
Posts: 94
Joined: Wed Apr 28, 2021 3:12 am

Re: const array in flash

Sat Sep 18, 2021 4:38 pm

Everything is in flash until it is loaded into RAM.
For programs like yours, this happens pretty much at the startup. Assuming that it all fits, of course.

There is effectively no case where you "want" it to live in flash - RAM accesses are much faster.
However, there are cases where it won't fit, and must be left in flash. In those cases, a fetch to flash must occur - and since this is many orders of magnitude slower than RAM access, it loads a block of memory and caches it. If it's really huge and you access it truly randomly, then there will likely be a high cache-miss ratio which will have it fetching from flash quite often, and the performance will be much worse than you may think.. but it will still execute.

cleverca22
Posts: 4626
Joined: Sat Aug 18, 2012 2:33 pm

Re: const array in flash

Sat Sep 18, 2021 4:41 pm

dshadoff wrote:
Sat Sep 18, 2021 4:38 pm
If it's really huge and you access it truly randomly, then there will likely be a high cache-miss ratio which will have it fetching from flash quite often, and the performance will be much worse than you may think.. but it will still execute.
if it is truely random, then youll always miss, and just waste cache space by pushing something else out of the cache

but there is a second window in the addr space, that gives you uncached flash access
then it will never be a cache hit, but it wont evict other things from the cache, so other things will run faster

User avatar
triss64738
Posts: 57
Joined: Wed Jun 16, 2021 5:13 pm
Location: masto/fedi: sys64738@hellsite.site
Contact: Website

Re: const array in flash

Sat Sep 18, 2021 4:52 pm

The above few posts make some good points, but if you want to put it in flash anyway, do this:

Code: Select all

#include <pico/platform.h>
const uint8_t __in_flash(huge_data_table)[65536] = { /* ... */ };
Accessing 'huge_data_table' as-is will go through the cache. This is good if you do many adjacent accesses, but very bad if you do random ones.. To circumvent the cache, do the following:

Code: Select all

const uint8_t* huge_data_table_uncached = (const uint8_t*)((size_t)huge_data_table | 0x03000000);
(I couldn't find a way to do it in a cleaner way using a Pico SDK macro.)

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 950
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: const array in flash

Sat Sep 18, 2021 5:13 pm

mschnell wrote:
Sat Sep 18, 2021 11:06 am
Without much thinking, I defined a big const array that is accessed by the software in a random way.
Later I wondered if that should clutter the flash cash. I took a look at the map file and found that regarding the placement, the compiler ignores the "const" and handles it as if it was a preloaded var in RAM.
This seems to be a GCC feature unless you make the array static as well as const.

lurk101
Posts: 964
Joined: Mon Jan 27, 2020 2:35 pm
Location: Cumming, GA (US)

Re: const array in flash

Sun Sep 19, 2021 2:15 am

triss64738 wrote:
Sat Sep 18, 2021 4:52 pm
The above few posts make some good points, but if you want to put it in flash anyway, do this:

Code: Select all

#include <pico/platform.h>
const uint8_t __in_flash(huge_data_table)[65536] = { /* ... */ };
Accessing 'huge_data_table' as-is will go through the cache. This is good if you do many adjacent accesses, but very bad if you do random ones.. To circumvent the cache, do the following:

Code: Select all

const uint8_t* huge_data_table_uncached = (const uint8_t*)((size_t)huge_data_table | 0x03000000);
(I couldn't find a way to do it in a cleaner way using a Pico SDK macro.)
That doesn't compile, but this does.

Code: Select all

const uint8_t* const huge_data_table_uncached = (const uint8_t*)((size_t)huge_data_table + 0x03000000);
Also you want a constant pointer to constant data, not just a constant pointer.

mschnell
Posts: 70
Joined: Wed Jul 28, 2021 10:33 am
Location: Krefeld, Germany

Re: const array in flash

Sun Sep 19, 2021 12:33 pm

dshadoff wrote:
Sat Sep 18, 2021 4:38 pm
Everything is in flash until it is loaded into RAM.
That is not true. By default any code stays in flash ("execute in place") . There are options to execute single functions or the whole project in RAM. but there is no automatic according to the Ram space. The remaining RAM space always is used as Heap.
-Michael

dshadoff
Posts: 94
Joined: Wed Apr 28, 2021 3:12 am

Re: const array in flash

Sun Sep 19, 2021 4:33 pm

mschnell wrote:
Sun Sep 19, 2021 12:33 pm
dshadoff wrote:
Sat Sep 18, 2021 4:38 pm
Everything is in flash until it is loaded into RAM.
That is not true. By default any code stays in flash ("execute in place") . There are options to execute single functions or the whole project in RAM. but there is no automatic according to the Ram space. The remaining RAM space always is used as Heap.
-Michael
The statement is indeed true, assuming the 'normal' configuration of a program loaded to flash and the Pico booting in non-debug configuration.
Before anything is executed, the SRAM is not yet in use, and everything that exists is on flash. I was referring to the situation before any code is executed (and obviously before any heap can be allocated by code, as none has executed yet).

Code does not execute from flash - the sheer volume of commands on the SPI bus would be insane, and performance would be terrible. It is loaded from Flash into an XIP cache for execution (from SRAM). It may then be flushed from the cache if the program requires more space than the XIP cache provides, but there is always cache allocated for this use (16KB as I recall - which may be sufficient for many small programs to completely exist). Code can also be force-loaded into SRAM by compiler directive, as you mentioned. Code loaded in this way does not need the XIP cache treatment in order to execute.

Regarding data however, other contributors to this thread have given specific examples of how that is treated.

Return to “SDK”