我有一个函数,它获取n
字节的输入缓冲区,并且需要一个n
字节的辅助缓冲区来处理给定的输入缓冲区。
(我知道vector在运行时分配内存,假设我正在使用一个使用静态预分配内存的向量。想象一下这是 NOT 一个STL向量。)
通常的方法是
void processData(vector<T> &vec) {
vector<T> &aux = new vector<T>(vec.size()); //dynamically allocate memory
// process data
}
//usage:
processData(v)
由于我在实时环境中工作,我希望提前预先分配我需要的所有内存。
缓冲区在启动时仅分配一次。我希望每当我分配一个向量时,我都会自动为我的processData
函数分配辅助缓冲区。
我可以使用模板功能
做类似的事情static void _processData(vector<T> &vec,vector<T> &aux) {
// process data
}
template<size_t sz>
void processData(vector<T> &vec) {
static aux_buffer[sz];
vector aux(vec.size(),aux_buffer); // use aux_buffer for the vector
_processData(vec,aux);
}
// usage:
processData<V_MAX_SIZE>(v);
然而,使用模板工作并不是很有趣(现在让我们重新编译所有内容,因为我更改了注释!),并且它强制我在使用此功能时进行一些簿记。
这个问题有没有更好的设计?
答案 0 :(得分:3)
我看不出你怎么能准确地得到你描述的内容。这样的事情对你来说可能是一个很好的妥协。
void processData(vector<T>& vec)
{
static vector<T> aux(vec.size());
if (vec.size() > aux.size()) {
aux.resize(vec.size());
}
...
}
答案 1 :(得分:1)
vector aux(vec.size(),aux_buffer); // use aux_buffer for the vector
STL是新的吗?还是自定义扩展程序?
典型的解决方案是使用自定义分配器。但是,这在代码中并不一定“更漂亮”。
Some intro slides(警告:powerpoint!)
Wikipedia
Google
答案 2 :(得分:1)
即使你成功地做到了这一点,它也可能达不到你想要的效果。根据您正在使用的操作系统以及它如何实现虚拟内存,您可能会发现lazy allocation
,其中只有部分内存分配实际上已分配并初始映射,而后续的页面将作为结果进行映射页面错误。如果您的操作系统有mlock
或等效操作系统,那么您可以解决此问题。
答案 3 :(得分:1)
我认为你可以在启动时预先分配和mlock()一个足够大的内存池,然后使用带有内存池分配器(Boost FSBA或你自己的)的常规STL容器。 / p>
我正在调查我们的实时软件,但测试显示我们的硬件上的内存分配足够快。
答案 4 :(得分:1)
让我说我正在使用矢量 它使用静态预分配内存
然后你应该能够在编译时获得预分配内存的大小(或最大大小)。 如果这样的向量的大小作为模板参数,那么使用processData函数会更容易。
template<class T, size_t sz>
class vector
{
enum { size = sz } //either max size
...
}
template<class Vector>
static void _processData(Vector &vec,Vector &aux)
{
// process data
}
template<class Vector>
void processData(Vector &vec) {
static aux_buffer[Vector::size];
//no need to pass size into constructor, as Vector type knows it already
Vector aux(aux_buffer); // use aux_buffer for the vector
_processData(vec,aux);
}
// usage:
vector<int, 30> v1;
vector<float, 40> v2;
//no need to specify template parameter explicitly
//every call uses its own function instance and its own buffer of different size
processData(v1);
processData(v2);
答案 5 :(得分:1)
这不是您需要担心的vector
,而是内存分配器。
你可以完美地创建一个内存分配器来预先分配它的内存,然后在构建时将它传递给向量,这就是Alloc
模板参数的用途!
为了确保内存不是“虚拟”分配,请在分配时触摸它。
scoped_array<byte> buffer = new byte[SIZE];
memset(buffer.get(), 0, SIZE);
现在,您“只需”实现一个自定义分配器,它引用此内存池并将其传递给向量实现:)
答案 6 :(得分:0)
你能创建一个包含向量和同样大小的缓冲区的小结构吗?然后你的矢量随身携带它的处理缓冲区。如果通过引用或指针传递它,则应避免复制开销。伪代码如下:
struct Container
{
vector<T> vec;
vector<T> buf;
Container(int size)
{
vec.reserve(size);
buf.reserve(size);
}
};
当前采用vector参数的任何函数都将采用Container
。
答案 7 :(得分:0)
可能你可以覆盖new和delete操作符,但是你必须管理它们 你自己的全部记忆。您可以在开头分配尽可能多的内存:
void* operator new (std::size_t size) throw (std::bad_alloc);
void* operator new[] (std::size_t size) throw (std::bad_alloc);
void operator delete (void* ptr) throw ();
void operator delete[] (void* ptr) throw ();