Definition of putchar/getchar causes code growth

View: New views
5 Messages — Rating Filter:   Alert me  

Definition of putchar/getchar causes code growth

by Wouter van Gulik :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi list,

Currently putchar is defined as
#define putchar(__c)   fputc(__c, stdout)

which causes C code like this:
putchar(' ')

To generate assembler like this:
lds r22,__iob+2
lds r23,(__iob+2)+1
ldi r24,lo8(32)
ldi r25,hi8(32)
call fputc

This is 8 bytes (lds == 4 bytes) for loading the stream pointer.
If we change this to a "real" putchar call we would save 8 bytes per
putchar call. the putchar call would then load the correct stream:

int putchar(int c)
{
        return fputc(stdout, c);
}

The cycle penalty would be the extra call and return.
IMHO losing 7,8 or 10 cycles per call for a gain of 8 bytes per call
seems very acceptable to me. Especially if it concerns functions like
putchar and friends.

Other opinions? Otherwise I will file a bug report.

Wouter



_______________________________________________
AVR-libc-dev mailing list
AVR-libc-dev@...
http://lists.nongnu.org/mailman/listinfo/avr-libc-dev

Re: Definition of putchar/getchar causes code growth

by Bernard Fouché :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi.

I just began yesterday to move from gcc-4.2.0/avr-libc-1.4.6 to
gcc-4.3.0/avr-libc-1.6.2 (with the patches taken from WINAVR0610).

I first experienced a significant code growth (about 4%) because of:

- functions like eeprom_read/write_byte() that now inline more code,
hence I had to write wrapper functions like you did in your example for
putchar(). In a previous run of 'hand optimization', I did replace
fputc() calls directly to 'myputc' (stream->putc()), sparing even more
bytes (the size of fputc()) while getting more speed (often the checks
performed in fputc() (i.e. (if((stream->flags...)) are useless (depends
on the application considered)).

- gcc-4.3.0 seems to automatically inline bigger static functions than
gcc-4.2.0. I have to use -finline-limit to a very low value like 10.

I now have a code size with gcc-4.3.0/avr-libc-1.6.2 a litle bit smaller
than with gcc-4.2.0/avr-libc-1.4.6. (and I will have to perform
extensive tests to check that the application still works :)) and I
reclaimed the 256 bytes of RAM that were previously lost because of
__clz_tab (my main reason for moving to a newer compilation chain)

IMHO the 'stock' distribution of avr-gcc/avr-libc should be tuned to
give results as good (hence small) as possible with -Os since most of
the traffic in the mailing lists seems code size oriented, so I have a
point of view similar to Wouter.

Or have link options like '-lprintf_min' for features that would be
compiled in different ways to meet the user goals.

Or have conditional compilation of headers according to the optimization
required, (so in Wouter's case putchar() would be kept as a function
call with -Os, but replaced with fputc() with -O2/3), however I dunno if
there is a macro or something already defined allowing this without
passing yet another -D option to the compiler.

  Bernard

Wouter van Gulik wrote:

> Hi list,
>
> Currently putchar is defined as
> #define     putchar(__c)   fputc(__c, stdout)
>
> which causes C code like this:
> putchar(' ')
>
> To generate assembler like this:
> lds r22,__iob+2
> lds r23,(__iob+2)+1
> ldi r24,lo8(32)
> ldi r25,hi8(32)
> call fputc
>
> This is 8 bytes (lds == 4 bytes) for loading the stream pointer.
> If we change this to a "real" putchar call we would save 8 bytes per
> putchar call. the putchar call would then load the correct stream:
>
> int putchar(int c)
> {  
>     return fputc(stdout, c);
> }
>
> The cycle penalty would be the extra call and return.
> IMHO losing 7,8 or 10 cycles per call for a gain of 8 bytes per call
> seems very acceptable to me. Especially if it concerns functions like
> putchar and friends.
>
> Other opinions? Otherwise I will file a bug report.
>
> Wouter
>
>
>
> _______________________________________________
> AVR-libc-dev mailing list
> AVR-libc-dev@...
> http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
>



_______________________________________________
AVR-libc-dev mailing list
AVR-libc-dev@...
http://lists.nongnu.org/mailman/listinfo/avr-libc-dev

Re: Definition of putchar/getchar causes code growth

by Moritz Struebe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Bernard Fouché schrieb:
>
>
> Or have conditional compilation of headers according to the
> optimization required, (so in Wouter's case putchar() would be kept as
> a function call with -Os, but replaced with fputc() with -O2/3),
> however I dunno if there is a macro or something already defined
> allowing this without passing yet another -D option to the compiler.
>
You can use
#ifdef |__OPTIMIZE_SIZE__

Cheers
Morty


|
_______________________________________________
AVR-libc-dev mailing list
AVR-libc-dev@...
http://lists.nongnu.org/mailman/listinfo/avr-libc-dev

Re: Definition of putchar/getchar causes code growth

by Dave N6NZ :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Bernard Fouché wrote:
> IMHO the 'stock' distribution of avr-gcc/avr-libc should be tuned to
> give results as good (hence small) as possible with -Os since most of
> the traffic in the mailing lists seems code size oriented, so I have a
> point of view similar to Wouter.

I'm with you on this one, and agree with your argument.  -Os is the
"common watering hole", so the libraries should bias that way also.

>
> Or have link options like '-lprintf_min' for features that would be
> compiled in different ways to meet the user goals.

This one make me squinty-eyed. In a former life I managed a group
responsible for product validation of a commercial C/C++ compiler, so
from that experience certain concepts wake me up from the deepest nap.

Every compilation switch multiplies the size of the test space. Now of
course there are times when it makes sense to add compilation switches
-- like floating point support in printf -- but there needs to be a
Really Good Reason.   I don't see that putc() rises to the level of
Really Good Reason.  I think there needs to be a clear and dramatic
payoff in either code size or performance to justify a switch, or
evidence that users are commonly replacing certain functions with their
own versions in order to justify the added testing complexity.

IMHO: reliable, small, tunable, in that order.

-dave


_______________________________________________
AVR-libc-dev mailing list
AVR-libc-dev@...
http://lists.nongnu.org/mailman/listinfo/avr-libc-dev

RE: Definition of putchar/getchar causes code growth

by Weddington, Eric-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

 

> -----Original Message-----
> From:
> avr-libc-dev-bounces+eweddington=cso.atmel.com@...
> [mailto:avr-libc-dev-bounces+eweddington=cso.atmel.com@nongnu.
> org] On Behalf Of Bernard Fouché
> Sent: Friday, July 04, 2008 8:54 AM
> To: Wouter van Gulik
> Cc: avr-libc-dev@...
> Subject: Re: [avr-libc-dev] Definition of putchar/getchar
> causes code growth
>
> Hi.
>
> I just began yesterday to move from gcc-4.2.0/avr-libc-1.4.6 to
> gcc-4.3.0/avr-libc-1.6.2 (with the patches taken from WINAVR0610).
>
> I first experienced a significant code growth (about 4%) because of:
>
> - functions like eeprom_read/write_byte() that now inline more code,
> hence I had to write wrapper functions like you did in your
> example for
> putchar(). In a previous run of 'hand optimization', I did replace
> fputc() calls directly to 'myputc' (stream->putc()), sparing
> even more
> bytes (the size of fputc()) while getting more speed (often
> the checks
> performed in fputc() (i.e. (if((stream->flags...)) are
> useless (depends
> on the application considered)).
>
> - gcc-4.3.0 seems to automatically inline bigger static
> functions than
> gcc-4.2.0. I have to use -finline-limit to a very low value like 10.
>
> I now have a code size with gcc-4.3.0/avr-libc-1.6.2 a litle
> bit smaller
> than with gcc-4.2.0/avr-libc-1.4.6. (and I will have to perform
> extensive tests to check that the application still works :)) and I
> reclaimed the 256 bytes of RAM that were previously lost because of
> __clz_tab (my main reason for moving to a newer compilation chain)
>
> IMHO the 'stock' distribution of avr-gcc/avr-libc should be tuned to
> give results as good (hence small) as possible with -Os since most of
> the traffic in the mailing lists seems code size oriented, so
> I have a
> point of view similar to Wouter.

The developers of the AVR toolchain are already aware of these issues. Yes, we agree that the stock distributions should be tuned to give the best, smallest results with -Os. The problem is one of resources; there are a limited number of people working on the AVR toolchain, and practically all are volunteers.

> IMHO: reliable, small, tunable, in that order.
>
> -dave

I certainly agree with Dave on this.

Reliability was the reason for the change to the EEPROM routines, as was discussed extensively on this list a while back before the changes went in.

Yes, it's unfortunate that GCC 4.3.x does more aggressive inlining, which is a detriment on the AVR causing code size increases. The inlining heuristics need to be tuned for the AVR port. It seems that this was only discovered *after* the release.

But at this point, the AVR developers have been working aggressively on the "reliability" factor. The GCC Regression Test Suite has been getting a lot of work for the AVR port. The AVR port is getting tested with the Regression Test Suite on an almost daily basis. Bugs that generate wrong-code, or involve internal compiler errors are getting fixed. However, the tradeoff is that bugs or problems involving optimizations are not getting as much attention, but they are getting some. Yes, we are aware of the issues and they will be addressed.

Keep the reports coming. :-)

Eric Weddington


_______________________________________________
AVR-libc-dev mailing list
AVR-libc-dev@...
http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
LightInTheBox - Buy quality products at wholesale price