Embedded C ++: use STL or not?

I have always been an embedded software engineer, but usually at level 3 or 2 of the OSI stack. I'm not really a guy. In general, I have always made telecommunication products, usually hand-held / cell phones, which usually means something like an ARM 7 processor.

Now I am in a more general embedded world, in a small launch, where I can go to "not very powerful" processors (there is a subjective bit) - I can not predict which one.

I read a lot about the debate about using STL in C ++ in embedded systems, and there is no clear answer. There are some minor concerns about portability, and some about code size or runtime, but I have two main problems:
1 - exception handling; I'm still not sure whether to use it (see Embedded C ++: use exceptions or not? )
2 - I strongly dislike dynamic memory allocation in embedded systems, due to the problems that it may introduce. Usually I have a buffer pool that is statically allocated at compile time and that only serves buffers of a fixed size (if there are no buffers, the system is reset). STL, of course, makes a lot of dynamic allocation.

Now I have to decide whether to use or refuse STL - for the whole company forever (it is included in some very strong s / w).

Which way am I jumping? It’s super-safe and will lose most of what C ++ makes up (imo, this is more than just defining a language) and maybe run into problems later or need to add a lot of exception handling and maybe some other code now?

I am tempted to just go with Boost , but 1) I’m not sure whether it will be ported to each embedded processor, I might want to use it and 2) on their website, they say that they do not guarantee / do not recommend some of it parts for embedded systems (especially FSM, which seems strange). If I go to Boost and we find the problem later.

+60
c ++ stl embedded
Feb 09 2018-10-09T00
source share
11 answers

It's super-safe and losing a lot of things is C ++ (imo, it's more than just defining a language) and it is possible to run into problems later or add a lot of exception handling and amp; maybe some other code now?

We have a similar debate in the game world, and people are coming down from both sides. As for the quoted part, why would you be worried about losing “most of what is C ++”? If this is not pragmatic, do not use it. It does not matter whether it is "C ++" or not.

Run some tests. Can you get around STL memory management in ways that satisfy you? If so, was it worth the effort? A lot of STL and boost problems are designed to solve simple problems, if you do not plan to avoid random allocation of dynamic memory ... Does STL solve a specific problem that you are facing?

Many people do STL in difficult conditions and are happy with it. Many people just shun it. Some people offer completely new standards . I do not think there is one correct answer.

+30
Feb 09 2018-10-02T00
source share

I work on embedded real-time systems every day. Of course, my definition of an embedded system may differ from yours. But we make full use of STL and exceptions and do not experience any unmanageable problems. We also use dynamic memory (with a very high speed, allocating a large number of packets per second, etc.). And we do not yet need to use any custom allocators or memory pools. We even used C ++ in interrupt handlers. We do not use momentum, but only because some state agency will not allow us.

This is our experience that you can really use in many modern C ++ functions in the embedded environment while you use your head and conduct your own tests. I highly recommend you use the third edition of Scott Meyer Effective C ++, as well as the Sutter and Alexandrescu C ++ coding standards, which will help you use C ++ with a reasonable programming style.

Edit: after you return to this 2 years later, let me post an update. We are much further in our development, and we finally hit spots in our code, where the standard library containers are too slow in high-performance environments. Here we really used special algorithms, memory pools and simplified containers. This is the beauty of C ++, but you can use the standard library and get all the good things that it provides for 90% of your use cases. You don’t throw it all away when you run into problems, you just manually optimize the problems.

+34
Feb 09 '10 at 3:05
source share

Other posts have addressed important issues with dynamic memory allocation, exceptions, and possible bloat code. I just want to add: don't forget about <algorithm> ! Regardless of whether you use STL vectors or simple C arrays and pointers, you can still use sort() , binary_search() , random_shuffle() , functions for creating and managing heaps, etc. These routines will almost certainly be faster and less buggy than the versions you create yourself.

Example: if you don’t think about it, the shuffle algorithm that you create yourself will most likely lead to distorted distributions ; random_shuffle() will not be.

+23
Feb 09 '10 at 2:32
source share

Electronic Arts wrote a long treatise on why STL is not suitable for developing embedded consoles and why they had to write their own. This is a detailed article, but the most important reasons were:

  • STL dispensers are slow, bloated, and inefficient.
  • Compilers are not really good at encrusting all these deep function calls.
  • STL allocators do not support explicit alignment
  • The STL algorithms that come with the GCC and MSVC STL are not very efficient because they are very platform incompatible and therefore miss a lot of microoptimizations that can make a big difference.

A few years ago, our company decided not to use STL at all, instead introducing our own container system that is as efficient as possible, easier to debug and more conservative in memory. It was a lot of work, but it paid off many times. But ours is a space in which products compete for how much they can squeeze in 16.6 ms with a given processor and memory size.

As for exceptions: they are slow on consoles, and anyone who tells you otherwise has not tried to sync them. A simple compilation with them will slow down the entire program due to the necessary prolog / epilogue code - measure it yourself if you do not believe me. This is even worse on processors than x86. For this reason, the compiler we use does not even support C ++ exceptions.

The increase in performance is not so much due to the fact that you avoid the cost of throw - it completely disables exceptions.

+19
Feb 09 '10 at 3:08
source share

Let me start by saying that I have not been doing embedded work for several years, and have never been in C ++, so my advice is worth every penny you pay for it ...

The templates used by STL will never generate code that you won’t need to generate, so I won’t worry about bloating the code.

STL does not throw exceptions on its own, so this should not be a concern. If your classes do not drop out, you should be safe. Divide the initialization of the object into two parts, let the constructor create an object with bare bones, and then perform any initialization that may fail in a member function that returns an error code.

I think that all container classes will allow you to define your own distribution function, so if you want to allocate from the pool, you can do it.

+13
Feb 09 '10 at 2:12
source share
  • for memory management, you can implement your own allocator, which requests memory from the pool. And all STL containers have a template for dispenser.

  • for exception, STL does not throw many exceptions, in general the most common are: out of memory, in your case, the system should reset, so you can reset in the distributor, others such as out of range, you can avoid this by the user.

  • so I think you can use STL in the embedded system :)

+4
Feb 09 2018-10-09T00
source share

It mainly depends on your compiler and the amount of memory. If you have more than a few KB of memory, dynamic memory allocation helps. If the malloc implementation from the standard library that you have is not configured for the size of your memory, you can write your own or there are good examples, for example mm_malloc from Ralph Hempel , which you can use to write new ones and delete statements from above.

I disagree with repeating mem that exceptions and stl containers are too slow or too bloated, etc. Of course, he adds a little more code than a simple C malloc, but judicious use of exceptions can make the code much clearer and avoid too many errors related to an error in C.

It should be borne in mind that STL distributors increase their power distributions by two, which means that sometimes it will perform some redistributions until it reaches the desired size, which you can prevent by using a backup , so it becomes just as cheap as one malloc of the desired size if you know the size to be allocated anyway.

If you have a large buffer in a vector, for example, at some point it can redistribute and ends up using a 1.5-fold memory size, which you intend to use at some point when redistributing and moving data. (For example, at some point it allocates N bytes, you add data through an append or insert iterator, and it allocates 2N bytes, copies the first N and frees N. At some point you allocate 3N bytes).

So, in the end, he has many advantages, and pays if you know what you are doing. You need to know a little about how C ++ works in order to use it in embedded projects without surprises.

And for a guy with fixed buffers and reset, you can always reset inside a new statement or something else if you have a shortage of memory, but that would mean that you made a bad design that could run out of memory.

The exception is ARM realview 3.1:

 --- OSD\#1504 throw fapi_error("OSDHANDLER_BitBlitFill",res); S:218E72F0 E1A00000 MOV r0,r0 S:218E72F4 E58D0004 STR r0,[sp,#4] S:218E72F8 E1A02000 MOV r2,r0 S:218E72FC E24F109C ADR r1,{pc}-0x94 ; 0x218e7268 S:218E7300 E28D0010 ADD r0,sp,#0x10 S:218E7304 FA0621E3 BLX _ZNSsC1EPKcRKSaIcE <0x21a6fa98> S:218E7308 E1A0B000 MOV r11,r0 S:218E730C E1A0200A MOV r2,r10 S:218E7310 E1A01000 MOV r1,r0 S:218E7314 E28D0014 ADD r0,sp,#0x14 S:218E7318 EB05C35F BL fapi_error::fapi_error <0x21a5809c> S:218E731C E3A00008 MOV r0,#8 S:218E7320 FA056C58 BLX __cxa_allocate_exception <0x21a42488> S:218E7324 E58D0008 STR r0,[sp,#8] S:218E7328 E28D1014 ADD r1,sp,#0x14 S:218E732C EB05C340 BL _ZN10fapi_errorC1ERKS_ <0x21a58034> S:218E7330 E58D0008 STR r0,[sp,#8] S:218E7334 E28D0014 ADD r0,sp,#0x14 S:218E7338 EB05C36E BL _ZN10fapi_errorD1Ev <0x21a580f8> S:218E733C E51F2F98 LDR r2,0x218e63ac <OSD\#1126> S:218E7340 E51F1F98 LDR r1,0x218e63b0 <OSD\#1126> S:218E7344 E59D0008 LDR r0,[sp,#8] S:218E7348 FB056D05 BLX __cxa_throw <0x21a42766> 

Doesn’t seem so scary, and no overhead is added inside the {} blocks or functions unless an exception is thrown.

+3
Feb 09 '10 at 6:37
source share

In addition to all the comments, I would suggest you read the C ++ Technical Performance Report , which specifically discusses topics that interest you: using C ++ in embedded (including hard real-time systems); how exception handling is usually implemented and what overhead it has; free distribution of resources for storage.

The report is really good, like debunks, in many popular C ++ performance tails.

+3
Feb 09 '10 at 10:36
source share

The open source project “Embedded Template Library (ETL)” addresses common STL problems used in embedded applications by providing / implementing a library:

  • deterministic behavior
  • “Create a set of containers whose size and maximum size will be determined at compile time. These containers should be basically the same as those delivered in the STL with a compatible API.
  • lack of dynamic memory
  • no RTTI required
  • little use of virtual functions (only if necessary)
  • fixed capacity container set
  • caching the contents of containers as a continuously allocated memory block.
  • reduced container code size
  • Typical smart listings
  • CRC Calculations
  • checksums and hash functions
  • Options = types of secure connections type
  • Selection of statements, exceptions, error handler, or error checking.
  • highly reliable testing
  • well-documented source code
  • and other functions ...

You can also consider the commercial C ++ STL for embedded developers provided by ESR Labs.

+3
Nov 10 '16 at 9:02
source share

The biggest STL issue on embedded systems is the memory allocation problem (which, as you said, causes a lot of problems).

I would seriously investigate creating my own memory management created by overriding the new / delete statements. I am pretty sure that with a little time it can be done, and it is almost certainly worth it.

As for the exception, I would not go there. Exceptions are a serious setback for your code because they force every single block ( { } ) to have code before and after, allowing you to catch the exception and destroy any objects contained inside. I don't have hard data on this, but every time I saw this problem arise, I saw overwhelming evidence of a massive slowdown caused by using exceptions.

Edit:
Since many people wrote comments that exception handling is not slower, I thought I would add this small note (thanks to those who wrote this in the comments, I thought it would be nice to add it here).

The reason for handling exceptions slows down your code because the compiler needs to make sure that every block ( {} ) from where the exception is thrown should free any objects inside it. This is the code that is added to each block, regardless of whether anyone ever throws an exception or not (because the compiler cannot tell at compile time whether this block is part of the exception chain).

Of course, this may be the old way of doing what has become much faster in new compilers (I'm not completely updated in C ++ compiler optimization). The best way to find out is to simply run some sample code, with the exceptions turned on and off (and which include several nested functions), and the time difference.

+1
Feb 09 '10 at 2:11
source share

In our embedded scanner project, we developed a board with an ARM7 processor, and STL did not cause any problems. Undoubtedly, the details of the project are important, since dynamic memory allocation cannot be a problem for many of the available boards today and the type of projects.

+1
Feb 19 '14 at 18:16
source share



All Articles