Code size optimziation.

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
rew
Posts: 383
Joined: Sat Jul 19, 2014 12:59 pm
Has thanked: 2 times
Been thanked: 14 times

Code size optimziation.

Post by rew »

Hi,
I have an application that is running out of flash. I'd rather not move to a bigger processor. (I have a sizeable batch of the smaller chips I like to eventually sell... )

Is there a good reason that functions in the .text segment are aligned to 16 bytes? My application is now almost 15 kbytes large, I need a 1k region for parameter storage, so I have only 15k available in my 16k device. Running at "72 bytes free" at last compile...

But looking for "what can I cut" in the mapfile: I have over 1200 bytes of "*fill*" in the text segment. Does aligning functions give a big performance increase?

That said...
On ARM everybody has loads of ".ld" files that end up being named individually in the makefile depending on the CPU being used. On AVR I just pass the name of the CPU to the compiler and all the rest is being taken care of. (on the other hand, maybe with AVR the linker doesn't throw a fit if you exceed the flash size.) Anyway, wouldn't it be nice/possible to modify the linker scripts with commandline arguments in such a way that we can eliminate most of the linker files?

So for example, in my current project I could use a 16k or a 32k chip. So I need to point to the two possible .ld files that are the same except for a single length=16k vs length=32k. However, as I've said before, THIS project can only use 15/16 or 31/32 of the 1k pages, as I need one page for the parameter storage. So now I'd have to create a custom linker-file for this project, while I much rather have a single parameter in my Makefile that says: max-flash-size=15k .
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Code size optimziation.

Post by Giovanni »

Hi,

It is not done for performance, it is done for timings, without alignment the code can shift over flash page boundaries, when this happens to a critical loop then execution times can be heavily affected.

If you don't have such concerns then function alignment can be safely disabled, BTW, it is not needed on slow devices with zero wait states.

Giovanni
rew
Posts: 383
Joined: Sat Jul 19, 2014 12:59 pm
Has thanked: 2 times
Been thanked: 14 times

Re: Code size optimziation.

Post by rew »

So would it be an idea to remove the ALIGN(16) from the ld files for "slow" (and small!) devices (F0)?

I don't see how the alignment helps in preventing a loop stradling a page boundary. Assuming you're talking about the flash pages called "flash page"....

If the previous function ends at 0xfc4 the loop in the next function has just as much chance of stradling the page boundary at 0xfff to 0x1000 when it starts at 0xfc4 or at 0xfd0.

Or am I mis-understanding something?

[update] Rereading you're saying "timing" not "performance". So we're talking about the case where I have a "for (i=0;i<10;i++)/* wait a few cycles */; " and that ends up starting at offset 0x30 from the beginning of the function, which when the function is aligned is aligned, but when the whole function is NOT aligned, it might straddle a page boundary. So by aligning the "weird timing dependency" only depends on the compiler options and the local function, but when things are not aligned, it also depends on other functions. So, just for that special case, we're throwing away 10% of my flash memory? Weird! Shouldn't the implementer who does such weird things need to add an "ALIGN" statement to his/her special function?
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Code size optimziation.

Post by Giovanni »

Without alignment a single change in the code shifts all the code from that point forward, with alignment only that specific function is affected because next functions remains aligned as before.

It is not that with alignment you get better performance, you get better repeatability after small changes.

This is particularly evident by running the test suite, without alignment even small changes yield very different results in benchmarks.

BTW, the alignment that matters is what is specified in makefile options.

Giovanni
rew
Posts: 383
Joined: Sat Jul 19, 2014 12:59 pm
Has thanked: 2 times
Been thanked: 14 times

Re: Code size optimziation.

Post by rew »

OK. Editing the linker script:

Code: Select all

Before: 
-rwxrwxr-x 1 wolff wolff 15292 Jan  3 14:19 build/ch.bin*
after:
-rwxrwxr-x 1 wolff wolff 14052 Jan  3 14:20 build/ch.bin*
I understand that the non-local effects of alignment can be annoying.

First if it makes a visible difference on the test-suite, apparently it DOES make a performance difference in some cases. Maybe not clearly positive or negative, but it makes a measurable difference on performance.

Secondly. the question is: Is the variation in test results important enough to waste 10% of memory by aligning every function to 16 bytes? Aligning only at say 15 points spread through the source base, would provide 90% of the benefits at 10% of the costs. Probably something that is difficult to achieve with the current compiler tools.

Would it be an idea to run the linker scritps through the preprocessor into say project.ld? Then we'd have a central

Code: Select all

#ifdef STM32F042x4
#define FLASH_SIZE 16k
#define RAM_SIZE 6k
#define ALIGN_TEXT 0
#endif
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Code size optimziation.

Post by Giovanni »

It is a real time OS, so determinism and repeatability are quite important IMHO.

Giovanni
Post Reply