内存有限的嵌入式系统中的STL [英] STL within embedded system with very limited memory

查看:160
本文介绍了内存有限的嵌入式系统中的STL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用带有64 KB SRAM的ARM Cortex M3处理器来构建嵌入式系统.目前,我正在寻找一种确保STL容器具有确定性性能的方法,其中包括确保我不会在运行时最终耗尽内存.

我主要关心STL容器如何执行动态内存分配.尽管我可以利用自定义分配器使这些结构从我留出的池中获取内存,但我需要为每个结构设置一个单独的池,以确保结构的一个实例不会占用另一个实例的空间. >

我正在与该项目的其他人员一起工作,他们不想关心内存的原始分配,而是希望能够利用众所周知的"数据结构(堆栈,队列,双端队列等).因此,我目前正在考虑围绕C数组构建包装器以提供这些结构.这将能够静态分配支持这些容器所需的内存,并允许其他开发人员根据编译器提供的代码大小信息,在运行时间之前知道它们已实例化的容器的大小.我认为,这保证了在运行时不会发生内存中断问题,并大大简化了系统设计.

另一种选择是在系统初始化时分配STL容器.初始化期过后,将不再发生其他动态内存分配.但是,据我所知,标准的C ++ STL数据结构不支持此功能-这就要求诸如栈之类的容器必须能够预先分配(类似于矢量).

我对围绕标准C数组构建类的建议有何评论?另外,有没有更简单的方法在编译时分配静态大小的STL容器,例如静态大小的堆栈或队列? (我知道使用vector可以实现此功能,但我不确定其他方法)

注意:我已经阅读了另一个问题(嵌入式C ++使用STL ),但是这个问题的作者并不清楚他们有多少内存(然后他们是如何使用ARM7进程的)或似乎正在考虑类似于我的解决方案.

第二注:我知道对于某些开发人员来说,64 KB的SRAM可能看起来像很多内存.实际上,我已经在内存显着减少的AVR处理器上进行了开发,因此我了解这种观点.但是,从我当前的(也许是无知的)观点来看,谈论STL容器时64 KB的内存并不多.

解决方案

这个问题有点困惑和奇怪.首先,让我们清除一些误解.

您通过名称提及堆栈,队列,双端队列".好吧,其中两个不是容器. stackqueue是容器适配器.瞧,他们实际上并没有直接存储元素.他们只是中介与他们的接口. stack确保您只能推,弹出和获取顶部元素. queue确保您只能后推,弹出前和获取前元素(认为还可以获取后元素).

容器适配器实际上将要使用的实际容器类型作为其模板参数之一.因此,如果需要,可以将stackstd::list一起使用.我不一定会建议(取决于您的用例),但是您可以.

容器适配器不关心内存;它不关心内存.是他们使用分配内存的容器.

如果您在内存受严格限制的系统中运行,则不会发现标准容器非常友好.即使您使用分配器为它们提供固定大小的内存缓冲区,这些分配器唯一可以阻止实际容器分配更多内存的操作就是引发异常.

例如,如果您有一个vector需要在2KB的内存中工作,则它的大小为1KB,并且尝试分配2.5KB以上的内存,则分配器不能会简单地返回2KB.它可以根据请求返回2.5KB或 throw std::bad_alloc.这些是您仅有的两个选择.分配器无法告诉vector它可以获得比其拥有的更多的内存,但没有所需的数量更多.

类似地,要求分配器提供 new 内存,可以将新分配的内存复制到其中.它不应仅在有更多可用内存的情况下提供相同的内存.这样做可能会在某些实现中引起问题.

分配器旨在提供不同的内存区域以供访问;它们的设计不适合限制容器本身的大小.

我的建议是找到 EASTL的副本.它确实是为这种事情而设计的.我链接到的Github存储库已修复了一些错误,依此类推,但仍然大致相同.这不是很糟糕的代码.它们的类似于STL的容器提供了大多数接口,因此它们几乎可以直接替换.但是它们提供了特殊功能来专门控制内存分配.

I'm currently in the process of building an embedded system, using an ARM Cortex M3 processor, with 64 KB of SRAM. At the moment, I'm looking for a way to ensure deterministic performance with STL containers, which includes ensuring that I cannot end up running out of memory at run-time.

I'm primarily concerned with how STL containers perform dynamic memory allocation. Although I can utilize a custom allocator to have these structures get memory from a pool which I set aside, I would need to setup a separate pool for each structure in order to ensure one instance of a structure cannot take up another instance's space.

I'm working with other individuals on this project who do not want to be concerned with raw allocation of memory and would prefer to be able to utilize the "well known" data structures (stack, queue, deque, etc). Therefore, I'm currently considering building wrappers around C-arrays to provide these structures. This would enable static allocation of the memory required to support these containers and allow the other developers to know the size of the container they have instantiated prior to run time, based on the code-size information provided by the compiler. In my opinion, this guarantees that memory outage issues cannot occur at runtime, and simplifies system design considerably.

The other option would involve allocation of STL containers at system initialization. After the initialization period, no additional dynamic memory allocation could occur. However, to my knowledge, the standard C++ STL data structures do not support this -- it would require that containers such as a stack be capable of being pre-allocated (similar to a vector).

I would appreciate any comments regarding my proposal to build classes around standard C-arrays? In addition, is there a simpler way to allocate a static size STL container, such as a static size stack or queue, at compile time? (I know this is possible with vector, but the others I'm not sure)

Note: I've read through another question (Embedded C++ to use STL or not), but the author of this question didn't make clear how much memory they had (other then how they were using an ARM7 process) or appear to be considering a solution similar to mine.

Second Note: I'm aware that to some developers, 64 KB of SRAM may look like a lot of memory. In fact, I've done development on AVR processors with significantly less memory, so I understand this perspective. However, from my current (perhaps uninformed) view, 64 KB of memory isn't much when talking about STL containers.

解决方案

This question is sort of confused and weird. First, let's clear up some misconceptions.

You mention "stack, queue, deque" by name. Well, two of these are not containers. stack and queue are container adapters. See, they don't actually directly store the elements; they simply mediate the interface to them. stack ensures that you can only push, pop, and get the top element. queue ensures that you can only push-back, pop-front, and get the front element (thought it also lets you get the back element).

The container adapters actually take as one of their template parameters the actual container type to use. So you could use a stack with a std::list if you want. I wouldn't necessarily suggest it (depending on your use case), but you could.

The container adapters don't care about memory; it's the containers that they use that allocate memory.

If you're running in such a tightly memory limited system, you're not going to find the standard containers to be terribly friendly. Even if you use allocators to give them fixed-size memory buffers, the only thing those allocators can do to stop the actual container from allocating more memory is to throw an exception.

For example, if you have a vector that needs to work within 2KB of memory, if it has a size of 1KB, and tries to allocate 2.5KB more, the allocator cannot simply return 2KB. It can either return 2.5KB as requested or throw std::bad_alloc. Those are your only two options. There is no way for the allocator to tell the vector that it can get more memory than what it has, but not as much as it wants.

Similarly, the allocator is required to provide new memory, freshly allocated memory that can be copied into. It is not supposed to provide the same spot of memory only with more of it available. Doing so will likely cause problems in some implementations.

Allocators are intended to provide different regions of memory for access; they're not well designed for limiting the size of the container itself.

My suggesting is to track down a copy of EASTL. It's really designed for this sort of thing. The Github repo I linked you to has some bug fixes and so forth, but it's still mostly the same. It's not a bad bit of code. Their STL-like containers provide most of the interface, so they can be mostly drop-in replacements. But they provide special functionality to specifically control memory allocations.

这篇关于内存有限的嵌入式系统中的STL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆