嵌入式环境中的STL

发布于 2024-09-25 23:08:05 字数 504 浏览 0 评论 0原文

我是一名 C++ 程序员,多年来一直听到这样的说法:STL不适合在嵌入式环境中使用,因此通常禁止在基于嵌入式环境的情况下使用我相信像 Boost 这样的 STL 库要强大​​得多,并且提供更快的速度和更快的速度。不太容易出错的开发方式(当然,语法有点吓人,但一旦过去,我认为它是一个真正的宝藏)。此外,我发现 STL 很重并且增加了代码最终占用空间的说法是荒谬的,因为因为它是模板化的,所以它只是一个将获得他要求的可编译代码,而不是整个 STL。

我的问题是,这种认为 STL 不适用于嵌入式环境的民粹主义(至少我周围的大多数人都这么认为)的原因是什么?

我确实看到了一个类似性质的问题,但在这里我希望有人帮助指出 STL 和嵌入式环境的一般优缺点。

编辑:所以在这里我将在收到回复时添加积分:
1. 可移植性问题
2.通过STL容器应对巨大的动态分配
3. STL很难调试
4. STL 中的深度函数调用会导致内联能力弱的编译器性能低下(函子的力量毫无用处!)

I am a C++ programmer and over the years have been subjected to hearing the notion that STL is not good for use in embedded environments and hence usually prohibited in usage for embedded environment based projects.I believe STL libraries like Boost are far more powerful and provide a much more faster & less error prone means of development(ofcourse the syntax is little intimidating but once past that i think it's a real treasure).Also, I find the claims that STL is heavy and increases final footprint of code absurd because since it is templatized one is only going to get compilable code which he asked for and not the entire STL.

My question is what are the reasons for this this populist(atleast most peeps around me think so) notion which calls STL is not for embedded enviornment?

I do see a question of similar nature but herein i am expecting help in pointing out the pros and cons in general about STL and embedded enviornment here.

Edit: so here I will add up the points as the replies come in:
1. Portability Issues
2. coping with huge dymanice allocations by STL containers
3. STL is hard to debug
4. Deep function calls in STL results in low performance for compilers weak with inlining (power of functors useless!)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

恰似旧人归 2024-10-02 23:08:05

STL 有很多问题(如 EASTL),在嵌入式系统或小规模系统上,主要问题通常是它管理内存的方式。 Aquaria 的 PSP 端口就是一个很好的例子。

不过,我的建议是在遵循假设之前先进行测试,如果测试显示您使用了太多的空间/处理器周期,那么也许一两个优化可以将其推入“可用”领域。

最后,boost 是基于模板的,所以如果你查看生成的模板代码的大小,它会受到与 STL 相同的影响。

编辑/更新:

澄清我最后的陈述(仅指boost VS STL)。在 C 中,您可以(ab)使用相同的代码在共享相同标头(或布局)的不同结构上执行相同的工作,但使用模板,每种类型可能会获得自己的副本(我从未测试过是否有任何编译器如果启用了“优化尺寸”,则足够聪明来执行此操作),即使它与刚刚生成的完全相同(在机器/装配级别上)。 boost 的优点是读起来更干净,并且里面塞满了更多的东西,但是由于大量(有时很大)的标头,这可能会导致编译时间很长。 STL 的好处是因为您可以传递您的项目而不需要下载/附带 boost。

STL has quite a few problems with it(as documented here by EASTL), on an embedded system, or small scale system, the main problem is generally the way in which it manages (its) memory. a good example of this was the PSP port of Aquaria.

My advise though is first test, before following assumptions, if the test are shows your using just too much space/processor cycles, then maybe an optimization or two could push it into the realm of 'usable'.

Finally, boost is template based, so if your looking at the size of generated template code, it'll suffer the same as STL.

Edit/Update:

To clear up my last statement (which was just refering to boost VS STL). In C, you can (ab)use the same code to do the same job on different structures sharing the same header (or layout), but with templates, each type might get its own copy (I've never test if any compilers are smart enough to do this if 'optimize for size' is enbaled), even though it exactly the same(on a machine/assembly level) as one thats just been generated. boost has the advantage of being a lot cleaner to read, and having far more things crammed into it, but that can lead to long compile times due to a copius amount of (somtimes huge) headers. STL gains because you can pass your project around and not require a download/accompanyment of boost.

月亮邮递员 2024-10-02 23:08:05

这取决于您所说的嵌入式是什么意思。在 Atmel8 系统上,内存很少。太少了,以至于你无法真正拥有合理的 malloc。在这种情况下,您希望非常明确地管理内存,可能使用您需要的类型的静态数组。如果你掌握了这些,那么你基本上就不需要大部分 STL 了。

在arm系统上,你有足够的内存。使用STL!

That depends on what you mean by embedded. On Atmel8 systems, there's very little ram. So little that you can't really have a reasonable malloc. You want, in this case, to manage memory very explicitly, probably with static arrays of the type you need. If you've got that, you basically have no need for most of the STL.

On arm systems, you've got plenty of ram. Use STL!

埋情葬爱 2024-10-02 23:08:05

我看到了这个演示文稿:嵌入式系统编程的标准 C++

模板的复杂性在于编译器而不是运行时系统,这部分是问题所在 - 因为我们不确定编译器能够完成多少优化。事实上,基于STL的C++代码应该比不使用模板的C++代码甚至C代码更紧凑、更快!

I came across this presentation: Standard C++ for Embedded Systems Programming

the bulk of the complexity with templates is with the compiler than in the runtime system and that's partly where the problem lies - as we don't know for sure how much of an optimization the compiler is able to accomplish. In fact C++ code based on STL is supposed to be more compact and faster than C++ code not using templates and even C code!

山川志 2024-10-02 23:08:05

模板导致更大的代码这一概念背后有一些逻辑。基本思想非常简单:模板的每个实例化本质上都会生成单独的代码。对于早期的编译器来说,这尤其成问题——因为模板(通常)必须放入标头中,模板中的所有函数都是内联的。这意味着,如果您在 10 个不同的文件中实例化了(例如)vector,那么您(理论上)拥有您使用的每个成员函数的 10 个独立副本,每个使用它的文件对应一个副本。

任何相当新的编译器(例如,不到 10 年)都会在链接器中具有一些逻辑来将它们合并在一起,因此跨 10 个文件实例化 vector 只会产生一个副本您在最终可执行文件中使用的每个成员函数。然而,无论好坏,一旦人们“知道”模板会产生臃肿的代码,很多人就不会再去看看它是否仍然正确。

另一点(仍然如此)是模板可以轻松创建一些相当复杂的代码。如果你自己用 C 语言编写东西,你通常会强烈地想要使用最简单的算法、集合等来完成这项工作——有足够的动力让你可能会检查最大数量等细节。您可能会遇到的一些项目,看看您是否可以通过一些非常简单的事情来摆脱困境。模板可以使使用通用集合变得如此容易,您不必费心检查类似的事情,因此(例如)您最终会得到构建和维护平衡树的所有代码,即使您只是最多存储(比如说)10 个项目,因此带有线性搜索的简单数组可以节省内存,并且通常运行速度更快。

There is some logic behind the notion that templates lead to larger code. The basic idea is pretty simple: each instantiation of a template produces essentially separate code. This was particularly problematic with early compilers -- since templates (typically) have to be put into headers, all the functions in a template are inline. That means if you have (for example) vector<int> instantiated in 10 different files, you (theoretically) have 10 separate copies of each member function you use, one for each file in which you use it.

Any reasonably recent compiler (less than, say, 10 years old) will have some logic in the linker to merge these back together, so instantiating vector<int> across 10 files will only result in one copy of each member function you used going into the final executable. For better or worse, however, once it became "known" that templates produce bloated code, a lot of people haven't looked again to see whether it remained true.

Another point (that remains true) is that templates can make it easy to create some pretty complex code. If you're writing things on your own in C, you're generally strongly motivated to use the simplest algorithm, collection, etc. that can do the job -- sufficiently motivated that you're likely to check into details like the maximum number of items you might encounter to see if you can get away with something really simple. A template can make it so easy to use a general purpose collection that you don't bother checking things like that, so (for example) you end up with all the code to build and maintain a balanced tree, even though you're only storing (say) 10 items at most so a simple array with linear searches would save memory and usually run faster as well.

小苏打饼 2024-10-02 23:08:05

我认为选择取决于您的目标平台。如果您有一个正确的 C++ 编译器并且不介意使用容器时动态分配的内存,那么我没有看到任何问题。

I think the choice depends on your targeted platform(s). If you have a correct C++ compiler and do not mind the dynamic allocated memory if you use containers, I don't see any problem.

筱武穆 2024-10-02 23:08:05

正如人们所说,有各种各样的“嵌入式”系统。我将给出我的观点,重点是安全关键和硬实时系统。

大多数安全关键系统的指南只是禁止使用动态内存分配。如果您永远不必担心 malloc/new 调用失败,那么设计程序就会变得更加容易和安全。对于可能发生堆碎片的长时间运行的系统,即使在具有大量内存的芯片/系统上,您也无法轻松证明内存分配不会失败(特别是当设备必须运行多年而无需重新启动时)。

在时间紧迫的情况下,动态内存分配和复杂对象实例化所涉及的不确定性通常太大而无法处理。这就是为什么许多在这些领域工作的程序员坚持使用 C。你可以查看 C 源代码并猜测一个操作需要多长时间。使用 C++,看起来简单的代码更容易花费比看起来更长的时间。那些在此类系统中使用 C++ 的人倾向于坚持使用简单的普通代码。通常速度很快但有时需要很长时间执行的代码比速度较慢但一致的代码更糟糕。

我在大型项目中所做的是将实时功能和关键功能与其他功能隔离开来。非关键的内容可以使用标准工具(例如 STL)来编写。只要操作系统不妨碍关键部分就没关系。如果我不能保证不存在此类交互,那么就根本不要使用这些工具。

As people have said there is a wide range of "embedded" systems. I'll give my perspective, which focuses on safety critical and hard real time systems.

Most guidelines for safety critical systems simply forbid the use of dynamic memory allocations. It is simply much easier and safer to design the program if you never have to worry about a malloc/new call failing. And for long running systems where heap fragmentation can occur, you can't easily prove that the memory allocation won't fail, even on a chip / system with large amounts of memory (especially when the device must run for years without restarting).

In scenarios where there are tight timing deadlines, the uncertainties involved in dynamic memory allocation and instantiation of complex objects are frequently too large to deal with. This is why many programmers who work in these areas stick with C. You can look at C source and guess how long an operation takes. With C++, it is easier for simple looking code to take longer than it appears to. Those who use C++ in such systems tend to stick to simple plain vanilla code. And code which usually is fast, but occasionally takes a long time to execute is worse than code that is slower but consistent.

What I've done in larger projects is isolate the real time and critical functions from the rest. The non-critical stuff can be written using standard tools like the STL. That's okay as long as the OS doesn't get in the way of the critical parts. And if I can't guarantee that there are no such interactions, then don't use the tools at all.

美人如玉 2024-10-02 23:08:05

我参与了一个嵌入式项目,该项目在一个非常受限的系统中使用 C++ 和 STL(内存只有几兆字节,低速 ARMv4)。在大多数情况下,STL 很棒,但有些部分我们必须跳过(例如,std::map 每个实例化需要 2-4k 代码 [相对于我们的 ROM 大小来说这是一个很大的数字],并且我们有我们自己定制的 std::bitset 替代品 [可能是 ~1k ROM])。但是,std::vector 和 std::list 非常有用,就像使用 boost::intrusive_ptr 进行引用计数一样(shared_ptr 太大了,每个对象大约 40 字节 RAM!)。

使用 STL 的一个缺点是,当异常关闭时,您无法进行错误恢复(这对我们来说是这样,因为异常和 RTTI 对我们的编译器来说并不便宜)。例如,如果此行代码中的某处内存分配失败(std::map 对象):

my_map[5] = 66;

您将看不到它,代码只会默默地继续前进;很可能该对象现在处于损坏状态,但直到很久以后你才会崩溃。

话虽如此,我们在 C++ 和 STL 方面取得了巨大成功。正如另一位发帖者所说,在您的系统上尝试一下并测量 STL 的哪些部分可以工作。附带说明一下,有一份关于 C++ 总体性能的出色技术报告,值得一读:
http://www.open-std.org/jtc1/sc22 /wg21/docs/TR18015.pdf

I was on an embedded project that used C++ and STL in a very constrained system (memory in a fraction of a megabyte, ARMv4 at low speed). For the most part, STL was great, but there were parts that we had to skip (for example, std::map required 2-4k of code per instantiation [which is a big number relative to our ROM size], and we had our own custom replacement for std::bitset [it was maybe ~1k ROM]). But, std::vector and std::list were very helpful, as was using boost::intrusive_ptr for reference counting (shared_ptr was way too big, about 40 bytes RAM per object!).

The one downside to using STL is that you have no error recovery when exceptions are turned off (which they were for us, as exceptions and RTTI were not cheap on our compiler). For example, if a memory allocation failed somewhere in the code in this line (std::map object):

my_map[5] = 66;

you wouldnt see it and the code would just silently keep moving forward; chances are the object is now in a broken state, but you wouldnt crash until much later on.

That being said, we had great success with C++ and STL. As another poster said, try it out on your system and measure which parts of STL work. As a side note, there's a great technical report on C++ performance in general that is a good read:
http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf

掩于岁月 2024-10-02 23:08:05

许多人认为(出于多种原因,例如可移植性)C++ 不太适合嵌入式环境。嵌入式环境有很多种,STL 当然适合其中的一些。

一般来说,当您需要为资源有限的环境选择任何东西时,“更强大”始终是一个令人恐惧的短语,因为您通常想要功能较弱且更可控的东西。特别是如果“更强大”意味着开发人员(或以后维护代码的人)对底层实现的了解较少。

Many think that (for many reasons, such as portability) C++ isn't a good fit for an embedded environment. There are many types of embedded environments and STL is certainly OK for some of them.

In general, 'more powerful' is always a phrase to fear when you need to choose anything for a resource constrained environment, as you often want something less powerful and more controllable. Especially if 'more powerful' means the developer (or whoever maintains the code later) would have less understanding of the underlying implementation.

篱下浅笙歌 2024-10-02 23:08:05

这取决于嵌入式系统的性质。

这样的系统可能有几千字节(或更少)的 RAM,也可能有很多兆字节甚至千兆字节。因此,内存限制可能是也可能不是问题。

如果系统有实时限制,STL 的某些部分或用法可能不适合您应用程序的某些部分。容器类严重依赖动态内存分配、重新分配和对象复制,而这通常是高度不确定的,因此当在时间关键的代码中使用时,您无法保证满足最后期限。

这并不是说 STL 不能使用,即使在实时应用程序中也是如此。但是您需要仔细设计代码,以便您知道在时间关键的过程中不会发生一些非确定性操作。

It depends on the nature of the embedded system.

Such a system may have a few kilobytes of RAM (or less), or it may have many megabytes or even gigabytes. So memory constraints may or may not be an issue.

If the system has real-time constraints, some parts or usages of STL may not be suited to some parts of your application. Container classes rely heavily on dynamic memory allocation, reallocation and object copying, and this is most often highly non-deterministic, so when used in time-critical code, you have no way of guaranteeing the meeting of deadlines.

That is not to say that it STL cannot be used, even in real-time applications. But you need to design the code carefully so that you will know that some non-deterministic operation will not occur during a time critical process.

恏ㄋ傷疤忘ㄋ疼 2024-10-02 23:08:05

对我来说,只有充分的理由,如果某些库不适合有限的约束或其大小可能会在以后出现问题,则不要使用它。如果这对你来说不是问题,那就去做吧。无论如何你都无法变得更好。

For me, only good reason, not to use some library if it does not fit in limited constraints or its size can be problem later. If that is not problem for you, go for it. In any case you can not get better.

青柠芒果 2024-10-02 23:08:05

我没有遇到在嵌入式系统中使用 STL 的任何缺点,并且我计划在我当前的项目中使用它。也加强一下。

I haven't experienced any downside to using the STL in embedded systems and I plan to use it in my current project. Boost as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文