Forum : ARM
Original Post
Post Information | Post |
---|---|
January 7, 2008 - 9:34pm
|
is it true the free GCC compiler is making slow and large code for the STM32 ? Any ideas ? |
Forum : ARM
Post Information | Post |
---|---|
January 7, 2008 - 9:34pm
|
is it true the free GCC compiler is making slow and large code for the STM32 ? Any ideas ? |
Hi,
Are you using the SmallPrintf linker option in RIDE? I don't think so.
The "native" printf in gcc is huge because it is designed for working in a unix-like environment, with files, streams, processes, etc. Basically, it is not suited for embedded applications. Most of the time it will not work in simple applications that do not provide a multi-tasking OS and a file system. (and even then, there is some porting to do... ;/ )
So we have written a small printf, that you can include in your project by selecting the associated option in the linker options. Or you can directly take the sources in \LIB\ARM\SMALL_PRINTF. There is also an even smaller version that does not handle floating point. You can use it by selecting the "no float printf" option, or take its sources in \LIB\ARM\E_STDIO.
These printfs use the IO_putchar function defined in the UART0_putchar library. Therefore, you will need to select the UART0_putchar option for seeing the printf options. (or you can include the sources of the three libraries.)
I recommend you open this example project for testing these different options:
C:\Program Files\Raisonance\Ride\Examples\ARM\test\test.prj
It even includes a "very small printf" that only handles one %d. It is enough for most common applications and can be easily modified for your needs. (%x, ...)
Best Regards,
Vincent
In any case, when you are comparing compilers, (not only for ARM/STM32) I recommend you keep the printf out. The reason is, it is mostly used for debugging purposes, and seldom appears in the final version of the "real applications". (even in applications that use the UART, you often end up removing it and using putchar directly) However, since it appears in all the benchmarks, most compiler makers spend more time optimizing it than the rest of the compiler, and it is not representative of the "real" overall performance of the compiler, which is what you are trying to evaluate when making a benchmark.
In the past there was a compiler that I will not name here (it is not sold anymore), that was very good for printf, because they had spent a lot of time optimizing this function (for the benchmarks), and quite bad for all the rest. They had the best benchmark results because of that, but in "real applications" and in benchmarks that did not count the printf, they were in the end of the list...
Since then, we take out the printf when calculating the code size in our benchmarks, or at least we display both results, with and without it. I recommend you do the same, if you want any meaningful results for your tests.
Best Regards,
Vincent
Finally, you will probably find that the GCC compiler is not as good as the commercial ones. (you get what you pay for ;) )
But the ratio should rather be around 2 to 1 or below than 11 to 1 as you see now...
Best Regards,
Vincent
I did select the small one ! the big one cant even fit in my 128kb stm32 mcu !
with the big I get linker error : code size too big !!
I cant see anywhere the option "very small printf" :-) only small on/off
I only use it for debug and only with the %d, I have another converter routine I can use anyway,
but it is a place for improvement, also I think many people uses printf even in their final products (I dont)
well I made other speed and code size test, using different floatingpoint calculations,
here the GCC perform a bit better, only 10% more code, but halve speed !
Hi,
If you are not using floats, you can select the "small no-float printf" linker option.
The very small printf is just a function of the example. It is not a linker option or library or anything complex like that.
search for this in the main.c:
#define VERYSMALLPRINT
and this:
#if VERYSMALLPRINT
I'm surprised you filled the flash, even with the printf from GCC...
Can you confirm that you have properly redirected the putchar to the printf? Did you select the "UART0_putchar" option? Can you send this project to me? (support@raisonance.com, say in the text that it's for Vincent)
Here are my results with the test example using the different printf options: (using optimization level 1)
A) no print at all, not even a call to putchar:
#define PRINT 0
code size=2152
B) print using verysmallprint
#define PRINT 1
#define VERYSMALLPRINT 1
"small printf" option = false
"small no-float printf" option = false
code size = 2368
C) print using small no-float printf
#define PRINT 1
#define VERYSMALLPRINT 0
"small printf" option = true
"small no-float printf" option = true
code size = 6084
D) print using small printf
#define PRINT 1
#define VERYSMALLPRINT 0
"small printf" option = true
"small no-float printf" option = false
code size = 16068
E) print using native GCC printf (I don't expect it to work, but still we can see its size...)
#define PRINT 1
#define VERYSMALLPRINT 0
"small printf" option = false
"small no-float printf" option = false
code size = 32580
Can you reproduce this?
Bets Regards,
Vincent
Hi vincent !
"small no-float printf" linker option
this saved me 7k !!
#define PRINT 1
#define VERYSMALLPRINT 1
"small printf" option = false
"small no-float printf" option = false
dont work I get compiler/linker errors
--------
I have
"small printf" option = yes
"small no-float printf" option = yes
and the #defines you talk about dont change a thing :-)
my program is 9964 bytes big with the printf commented out
and 14784 bytes with a few lines if printf :-)
this is with no compiler uptimize, I dont really gain anything with the uptimizer !!
if you have a few minutes I will be happy to zip my project and mail to you ?
Hi,
Are you using the test example or your own? The defines I talked about only work in this example. They are part of it, not some special names recognized by the compiler or linker, (we would have used pragmas or "real options" for this) so I don't expect them to work in other projects, unless you copy the associated code from the example to your project... (check later in the example code to see what they do and how)
You can send me your project, I will look at it. But I think it would be easier if we both work on the example from RIDE. Then, when you understand all the different possible mechanisms, it will be easy for you to implement the one you want in your project.
Best Regards,
Vincent
The documentation doesn't mention the "small no-float printf" linker option. :(
Should the "small no-float printf" linker option be specified in addition to "small printf", or instead of it?
In other words: The Linker settings allow both "small no-float printf" and "small printf" to be selected simultaneously - should they be mutually exclusive?
Hi
The selection of these two options is not clear enough.
The "small no float printf" can be selected only in the case you have already chosen the "small printf" option.
To sumup here is how the link will be done in the different cases:
+ If only "small printf" is selected => it includes small printf library.
+ If only "small no float printf" is selected => it does not do anything.
+ If "small printf" and "small no float printf" are selected => it includes small no float printf library which is smaller.
Best regards,
Matloub