Re: size of exception handling (Was: performance of exception handling)

2020-05-13 Thread Jonathan Wakely via Gcc
On Tue, 12 May 2020, 10:15 Oleg Endo,  wrote:
>
> On Tue, 2020-05-12 at 09:20 +0200, Freddie Chopin wrote:
> >
> > I actually have to build my own toolchain instead of the one provided
> > by ARM, because to really NOT use C++ exceptions, you have to recompile
> > the whole libstdc++ with `-fno-exceptions -fno-rtti` (yes, I know they
> > provide the "nano" libraries, but I the options they used for newlib
> > don't suit my needs - this is "too minimized"). If you pass these two
> > flags during compilation and linking of your own application, this
> > disables these features only in your code. As libstdc++ is compiled
> > with exceptions and RTTI enabled, ...
>
> IMHO this is a conceptual fail of the whole concept of using pre-
> compiled pre-installed libraries somewhere in the toolchain, in
> particular for this kind of cross-compilation scenario.


The concept works well in other scenarios though. Not everybody has
the same use case or the same needs.


>   Like you say,
> when we set "exceptions off" it usually means for the whole embedded
> app, and the whole embedded app usually means all the OS and runtime
> libraries and everything, not just the user code.
>
> One option is to not use the pre-compiled toolchain libstc++ but build
> it from source (or use another c++ std lib of your choice), as part of
> the whole project, with the desired project settings.


Yes, IMO that's probably the right option if there is no pre-compiled
toolchain that matches your desired configuration.

If there are properties of libstdc++ that make it more difficult than
necessary, we want to know about them.


>
> BTW, just to throw in my 2-cents into the "I'm using MCU" pool of
> pain/joy ... in one of my projects I'm using STM32F051K6U6, 32 KB
> flash, 8 KB RAM, running all C++ code with shared C++ RPC libraries to
> communicate with other (bigger) devices.  Exceptions, RTTI, threads
> have to be turned off and only the header-only things from the stdlib
> can be used and no heap allocations.


Are you using headers that are not part of the freestanding subset? Which ones?

A future version of the C++ standard is probably going to expand the
headers that should be part of freestanding (or replace the concept of
freestanding with something more useful) so it would be good to know
what parts of the standard library people are actually using on
devices like that.


> Otherwise the thing doesn't fit.
> Don't feel like rewriting the whole thing either.  There are some
> annoyances when turning off exceptions and RTTI which results in
> increased code maintenance.


Such as?


> I'd definitely be good and highly
> appreciated if there were any improvements in the area of exception
> handling.
>
> Cheers,
> Oleg
>


Re: size of exception handling (Was: performance of exception handling)

2020-05-13 Thread David Brown

On 13/05/2020 00:48, Jonathan Wakely via Gcc wrote:

On Tue, 12 May 2020 at 23:39, Jonathan Wakely wrote:

On Tue, 12 May 2020, 21:57 Freddie Chopin,  wrote:

Anyway... If you have to recompile the toolchain, the problem is still
there. Most of the people (like 99,666%) will not do that for various
reasons. Some don't know how, some use only Windows, some don't have
time to deal with the compilation (the whole toolchain takes around an
hour here, but this excludes the time to prepare the script that builds
it), some other consider the toolchain provided by MCU vendor (or by
ARM) as "tested to work correctly" so they don't want to replace that
with their custom built solution, and so on, and so on...


There is no one-size-fits-all solution that gives everybody their
ideal set of defaults, so we provide configuration options to tune
things for your needs. Complaining that you have to rebuild things to
get different defaults seems silly. Would you prefer we don't offer
the options at all?


And I also never said that every user should rebuild the toolchain.
The options can be used by vendors providing a toolchain for their
hardware, if the verbose handler (or exceptions in general!) are not
appropriate for their users. Just because something isn't the default,
doesn't mean every user needs to change it themselves.


I think complaining about extra unnecessary code (such as string 
handling for std::terminate) is justified - but the complaints should 
not be directed at the gcc or libstdc++ folks.  As you say, /you/ 
provide the options - if the vendors make poor choices of options, then 
it is /they/ who should get the bug reports and complaints.


One option that would be nice (I don't know if it is realistic), would 
be to say that the code should never stop normally.  On many embedded 
systems, main() never exits.  std::terminate() doesn't need any code 
except perhaps to reset the processor (that will be target-specific, of 
course).  exit() can never be called - there is no need for atexit 
functions, terminate handlers, global destructors, or any of the other 
machinery used for controlled shutdown and ending of a program.





And if writing a script and waiting an hour is too much effort to
reduce unwanted overhead, then I guess that overhead isn't such a big
deal anyway.



There are, as Freddie mentions, many other reasons for end-users not 
building their own toolchains.  I have built many cross-gcc toolcahins 
over the years (starting with a gcc 2.95 m68k toolchain over 20 years 
ago, IIRC).  But for most professional embedded development, pre-built 
toolchains from vendors are a requirement - home-built is simply not an 
acceptable option.  Time and effort don't come into it.  (This is a good 
thing for gcc - a fair number of major gcc developers work for companies 
that earn money selling pre-built toolchains.)


Re: size of exception handling (Was: performance of exception handling)

2020-05-12 Thread Jonathan Wakely via Gcc
On Tue, 12 May 2020 at 23:39, Jonathan Wakely wrote:
> On Tue, 12 May 2020, 21:57 Freddie Chopin,  wrote:
> > Anyway... If you have to recompile the toolchain, the problem is still
> > there. Most of the people (like 99,666%) will not do that for various
> > reasons. Some don't know how, some use only Windows, some don't have
> > time to deal with the compilation (the whole toolchain takes around an
> > hour here, but this excludes the time to prepare the script that builds
> > it), some other consider the toolchain provided by MCU vendor (or by
> > ARM) as "tested to work correctly" so they don't want to replace that
> > with their custom built solution, and so on, and so on...
>
> There is no one-size-fits-all solution that gives everybody their
> ideal set of defaults, so we provide configuration options to tune
> things for your needs. Complaining that you have to rebuild things to
> get different defaults seems silly. Would you prefer we don't offer
> the options at all?

And I also never said that every user should rebuild the toolchain.
The options can be used by vendors providing a toolchain for their
hardware, if the verbose handler (or exceptions in general!) are not
appropriate for their users. Just because something isn't the default,
doesn't mean every user needs to change it themselves.

And if writing a script and waiting an hour is too much effort to
reduce unwanted overhead, then I guess that overhead isn't such a big
deal anyway.


Re: size of exception handling (Was: performance of exception handling)

2020-05-12 Thread Jonathan Wakely via Gcc
On Tue, 12 May 2020, 21:57 Freddie Chopin,  wrote:
>
> On Tue, 2020-05-12 at 12:07 +0100, Jonathan Wakely wrote:
> > You're talking about C++ exceptions in general, but the problems you
> > mention seems to be issues with specific implementation properties.
>
> Possibly true, but this argument - that all the problems are related to
> specific implementation and thus can be easily fixed


I didn't say anything about it being easy to fix.

I'm just trying to stop misinformation about std::terminate requiring
string handling or I/O, which isn't true for C++ in general, and isn't
even true for libstdc++ because it's configurable. If you want a
smaller EH runtime, that's already possible with libstdc++. Could it
be even smaller? Yes, probably, but we need bug reports or concrete
suggestions, not outdated or misleading claims about optional
properties of the libstdc++ runtime.


> - is the same for
> years and yet the problem is still there (; I guess that if this could
> be easily fixed, then it would be done years ago. Along with the
> performance and non-deterministic execution issues...

Nobody said it can easily be fixed though.

> > If the comments above are referring to the libstdc++ verbose
> > terminate
> > handler, that's configurable. Configuring GCC with
> > --disable-libstdcxx-verbose will disable that, and so will building
> > libstdc++ with -fno-exceptions. That was fixed years ago.
>
> True, sorry for the confusion, indeed I was talking about verbose
> terminate handler. I check the state of C++ exceptions for MCUs only
> once every few years, so that's why I got that mixed with
> std::terminate(). I use my custom compilation with disabled exceptions
> (toolchain & libstdc++ built with -fno-exceptions -fno-rtti) and this
> works perfectly fine.

It's been a few years since we changed anything, because disabling the
verbose handler solved one of the biggest issues.

> Anyway... If you have to recompile the toolchain, the problem is still
> there. Most of the people (like 99,666%) will not do that for various
> reasons. Some don't know how, some use only Windows, some don't have
> time to deal with the compilation (the whole toolchain takes around an
> hour here, but this excludes the time to prepare the script that builds
> it), some other consider the toolchain provided by MCU vendor (or by
> ARM) as "tested to work correctly" so they don't want to replace that
> with their custom built solution, and so on, and so on...

There is no one-size-fits-all solution that gives everybody their
ideal set of defaults, so we provide configuration options to tune
things for your needs. Complaining that you have to rebuild things to
get different defaults seems silly. Would you prefer we don't offer
the options at all?

If you have concrete suggestions for improvements or can identify
places we can improve, I'd like to hear them. If you just want to
complain about C++ exceptions, that's not very helpful.


Re: size of exception handling (Was: performance of exception handling)

2020-05-12 Thread Freddie Chopin
On Tue, 2020-05-12 at 12:07 +0100, Jonathan Wakely wrote:
> You're talking about C++ exceptions in general, but the problems you
> mention seems to be issues with specific implementation properties.

Possibly true, but this argument - that all the problems are related to
specific implementation and thus can be easily fixed - is the same for
years and yet the problem is still there (; I guess that if this could
be easily fixed, then it would be done years ago. Along with the
performance and non-deterministic execution issues...

> If the comments above are referring to the libstdc++ verbose
> terminate
> handler, that's configurable. Configuring GCC with
> --disable-libstdcxx-verbose will disable that, and so will building
> libstdc++ with -fno-exceptions. That was fixed years ago.

True, sorry for the confusion, indeed I was talking about verbose
terminate handler. I check the state of C++ exceptions for MCUs only
once every few years, so that's why I got that mixed with
std::terminate(). I use my custom compilation with disabled exceptions
(toolchain & libstdc++ built with -fno-exceptions -fno-rtti) and this
works perfectly fine.

Anyway... If you have to recompile the toolchain, the problem is still
there. Most of the people (like 99,666%) will not do that for various
reasons. Some don't know how, some use only Windows, some don't have
time to deal with the compilation (the whole toolchain takes around an
hour here, but this excludes the time to prepare the script that builds
it), some other consider the toolchain provided by MCU vendor (or by
ARM) as "tested to work correctly" so they don't want to replace that
with their custom built solution, and so on, and so on...

Regards,
FCh



Re: size of exception handling (Was: performance of exception handling)

2020-05-12 Thread Jonathan Wakely via Gcc
On Tue, 12 May 2020 at 09:17, Freddie Chopin wrote:
> The problem with C++ exceptions is that even in the most
> trivial of the programs and even if you don't explicitly
> use/catch/throw them, they instantly eat around 60 kB of ROM and quite
> a lot of RAM. With some hacking you can get down to about 20 kB of ROM
> (by overriding a lot of string formatting code and overriding
> std::terminate()),

You're talking about C++ exceptions in general, but the problems you
mention seems to be issues with specific implementation properties.

If the comments above are referring to the libstdc++ verbose terminate
handler, that's configurable. Configuring GCC with
--disable-libstdcxx-verbose will disable that, and so will building
libstdc++ with -fno-exceptions. That was fixed years ago.

If there are remaining problems where I/O and string routines get
dragged in without exceptions and the verbose terminate handler,
please report bugs against libstdc++. I would expect heroics to be
needed for a tiny footprint, but it should be possible to get a small
footprint just by rebuilding with the right options and flags.


Re: size of exception handling (Was: performance of exception handling)

2020-05-12 Thread Oleg Endo
On Tue, 2020-05-12 at 09:20 +0200, Freddie Chopin wrote:
> 
> I actually have to build my own toolchain instead of the one provided
> by ARM, because to really NOT use C++ exceptions, you have to recompile
> the whole libstdc++ with `-fno-exceptions -fno-rtti` (yes, I know they
> provide the "nano" libraries, but I the options they used for newlib
> don't suit my needs - this is "too minimized"). If you pass these two
> flags during compilation and linking of your own application, this
> disables these features only in your code. As libstdc++ is compiled
> with exceptions and RTTI enabled, ...

IMHO this is a conceptual fail of the whole concept of using pre-
compiled pre-installed libraries somewhere in the toolchain, in
particular for this kind of cross-compilation scenario.  Like you say,
when we set "exceptions off" it usually means for the whole embedded
app, and the whole embedded app usually means all the OS and runtime
libraries and everything, not just the user code.

One option is to not use the pre-compiled toolchain libstc++ but build
it from source (or use another c++ std lib of your choice), as part of
the whole project, with the desired project settings.


BTW, just to throw in my 2-cents into the "I'm using MCU" pool of
pain/joy ... in one of my projects I'm using STM32F051K6U6, 32 KB
flash, 8 KB RAM, running all C++ code with shared C++ RPC libraries to
communicate with other (bigger) devices.  Exceptions, RTTI, threads
have to be turned off and only the header-only things from the stdlib
can be used and no heap allocations.  Otherwise the thing doesn't fit. 
Don't feel like rewriting the whole thing either.  There are some
annoyances when turning off exceptions and RTTI which results in
increased code maintenance.  I'd definitely be good and highly
appreciated if there were any improvements in the area of exception
handling.

Cheers,
Oleg



Re: size of exception handling (Was: performance of exception handling)

2020-05-12 Thread Freddie Chopin
On Mon, 2020-05-11 at 17:14 +0200, Moritz StrĂ¼be wrote:
> I just wanted to point out that Herbceptions do not only fix
> performance 
> issues, but also code-size problems. While anything below 4GB of RAM
> is 
> considered under-powered for a PC, typical deep embedded
> environments 
> have something around 32k of program memory and 2K of ram. And even 
> those running Linux often have around 32MB program memory and 8MB of 
> RAM. Also most of these systems are very cost sensitive, so each
> byte 
> matters. Therefore RTTI and exceptions are one of the main reasons
> why 
> parts of the embedded community consider C++ unusable: They do some 
> experiments using C++ and the code size explodes.  And even if you
> know 
> what you are doing and turn interrupts and RTTI off, adding a 
> std::nothrow to every "new" to do decent error handling is pretty 
> annoying. Not mentioning the parts of the C++ library that don't
> provide 
> exception-free error-handling.
> 
> So yes, improving the performance is nice, but ISO C++ will still be 
> unusable for most computer systems: There are way more emdedded
> systems 
> with less than 32MB program memory out there than PCs, Servers and 
> mobile phones together.

Very nice that Moritz finally mentioned it (; The world of deep
embedded is usually forgotten by all the language committees and people
who are in charge. That's why the proposal by Herb is a real surprise
and I really hope it could be implemented someday.

The numbers above are maybe a bit too strict. A typical ARM Cortex-M
chip can have up to 2 MB of ROM and 512 kB of RAM, but I would say that
usually it has around 128-256 kB of ROM and somewhere around 16-64 kB
of RAM. The problem with C++ exceptions is that even in the most
trivial of the programs and even if you don't explicitly
use/catch/throw them, they instantly eat around 60 kB of ROM and quite
a lot of RAM. With some hacking you can get down to about 20 kB of ROM
(by overriding a lot of string formatting code and overriding
std::terminate()), but this is still too much for a feature you
actually don't use.

I actually have to build my own toolchain instead of the one provided
by ARM, because to really NOT use C++ exceptions, you have to recompile
the whole libstdc++ with `-fno-exceptions -fno-rtti` (yes, I know they
provide the "nano" libraries, but I the options they used for newlib
don't suit my needs - this is "too minimized"). If you pass these two
flags during compilation and linking of your own application, this
disables these features only in your code. As libstdc++ is compiled
with exceptions and RTTI enabled, they get pulled during link anyway,
bloating the binary size with a functionality you don't use and can't
use - every throw from the library ends up as std::teminate() anyway.
That's why the statement by Herb that C++ exceptions are never zero-
cost when not used is perfectly true.

The performance is also an issue. Article I've read sometime ago
mentioned that a trivial throw out of a single function takes about
7000-1 clock cycles until it is catched, which is unacceptable for
any real-time solution (normal return with error handling would take at
most a few dozen). But the size issue is a blocker for deep embedded,
then the performance and deterministic behaviour are only secondary
issues in such environment.

Regards,
FCh