C ++ preallocation of memory in real time

I have a function that receives an input buffer of n bytes and needs an auxiliary buffer of n bytes to process this input buffer.

(I know that a vector allocates memory at runtime, say I use a vector that uses static predefined memory. Imagine that it is NOT an STL vector.)

Usual approach

 void processData(vector<T> &vec) { vector<T> &aux = new vector<T>(vec.size()); //dynamically allocate memory // process data } //usage: processData(v) 

Since I work in real time, I want to preallocate all the memory that I need in advance.

The buffer is allocated only once at startup. I want that whenever I select a vector, I automatically allocate an auxiliary buffer for my processData function.

I can do something similar with a template function

 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); 

However, working with templates is not very pleasant (now let me recompile everything, since I changed the comment!), And this forces me to do some accounting reporting whenever I use this function.

Are there any nicer designs around this problem?

+7
c ++ memory-management real-time
source share
8 answers

I do not understand how you can get exactly what you described. Something like this can be a good compromise for you.

 void processData(vector<T>& vec) { static vector<T> aux(vec.size()); if (vec.size() > aux.size()) { aux.resize(vec.size()); } ... } 
+3
source share

vector aux(vec.size(),aux_buffer); // use aux_buffer for the vector

Is this new in STL? Or custom extension?

A typical solution would be to use a custom dispenser. However, this is not necessarily β€œprettier” in the code.

Some built-in slides (warning: powerpoint!)
Wikipedia
Google

+1
source share

Even if you succeed in doing this, he may not achieve what you want. Depending on which OS you use and how it implements virtual memory, you may find that you get lazy allocation , where only part of your memory allocation is actually allocated and displayed first, and subsequent pages are displayed later as a result of page faults. If your OS has mlock or equivalent, you can get around this.

+1
source share

I think you could pre-allocate and mlock () a large enough memory pool at startup, and then use regular STL containers with memory pool allocators ( Boost FSBA or your own).

I studied this for our software in real time, but tests showed that the memory allocation on our devices is fast enough for our purposes.

+1
source share

let's say i use a vector that uses static predefined memory

Then you should be able to get the size (or maximum size) of the pre-allocated memory at compile time. If such a vector had its size as an argument to the template, then working with the processData function would be easier.

 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); 
+1
source share

This is not a vector you need to worry about, it is a memory allocator.

You can perfectly create a memory allocator that preallocates its memory and then passes it to the vector when it is created, which is for the Alloc template parameter for!

And to make sure that the memory is not "actually" allocated, tap it when you allocate it.

 scoped_array<byte> buffer = new byte[SIZE]; memset(buffer.get(), 0, SIZE); 

Now you just need to implement your own allocator, which refers to this memory pool and passes it to the vector implementation :)

+1
source share

Could you create a small structure containing your vector and buffer of the same size? Then you will have your own vector transfer of the processing buffer with it, wherever it is. If you pass it by reference or index, you should avoid copying overhead. Following is the pseudo code:

 struct Container { vector<T> vec; vector<T> buf; Container(int size) { vec.reserve(size); buf.reserve(size); } }; 

Any function that currently accepts your vector argument then accepts a Container .

0
source share

You may be able to override new and delete statements, but you will have to manage all your memory as you wish. You can allocate as much memory as you want at the beginning:

 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 (); 
0
source share

All Articles