Re: size of exception handling (Was: performance of exception handling)
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)
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)
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)
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)
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)
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)
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)
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