1# Memory allocation {#dsppp_memory_allocator} 2 3By default, `malloc` is used. 4 5```cpp 6Vector<float32_t,NB> 7``` 8 9is allocating a vector of dimension `NB` (known at build time) and datatype `float32_t`. 10 11The definition of the `Vector` template is: 12 13```cpp 14template<typename P, 15 int L=DYNAMIC, 16 template<int> typename Allocator = TMP_ALLOC> 17struct Vector:Vector_Base<P> 18``` 19 20It means that by default the memory allocator is `TMP_ALLOC`. 21 22This `TMP_ALLOC` is a `#define` and can be changed if you define it before including any header from the library. 23 24An allocator should implement a template like: 25 26```cpp 27template<int L> 28struct malloc_allocator { 29 /* Dynamic dimension allocations (L<0) */ 30 static char* allocate ( vector_length_t sz) noexcept; 31 32 /* Dimension L know at build time (L > 0) */ 33 static char* allocate ( ) noexcept; 34 35 static void destroy ( char* ptr ) noexcept; 36 37}; 38``` 39 40It has no state because in practice we observed that compilers were generating more efficient code without state in the memory allocator template. 41 42If you don't want to use a `malloc` based memory allocator, you can replace it with your own memory allocator and implement an API like the one just shown in `malloc_allocator`. 43 44For instance, often in DSP pipelines, the dimensions of the vectors and matrixes are fixed and known at build time. 45In that case, you could replace the memory allocator by one using memory pools. 46 47With memory pools, allocation is nearly cost free and there is no fragmentation. 48 49The test framework of the library is providing an example in `allocator.h` and `allocator.cpp`. 50 51There are two memory allocators: 52 531. `stat_allocator` is a `malloc` based allocator that is making statistics on the memory allocations and how many buffers of each dimension is required 54 552. `pool_allocator` can use the data generated by `stat_allocator`to pre-allocate memory pools that will be then used for the memory allocations. The memory pools are also creating aligned buffers. 56 57It is no more difficult (and less difficult) than allocating temporary buffers in CMSIS-DSP. 58 59You could define the `TMP_ALLOC` with: 60 61```cpp 62#if defined(POOL_ALLOCATOR) 63#define TMP_ALLOC pool_allocator 64#else 65#define TMP_ALLOC stat_allocator 66#endif 67``` 68 69You use `stat_allocator` by default. When your code is working, you switch to `pool_allocator` to have better performance and determinism. 70 71Another possibility is to use different vector types: 72 73```cpp 74template<typename P,int L=arm_cmsis_dsp::DYNAMIC> 75using PVector = Vector<P,L,pool_allocator>; 76``` 77 78Note that you cannot avoid using `TMP_ALLOC` because some functions in the library are creating temporary objects. For instance, if you want to make an identity matrix, you can use ` mk_identity` that will make a memory allocation using `TMP_ALLOC` 79 80Also note that if you create a vector with: 81 82```cpp 83Vector<float32_t> v(NB); 84``` 85 86then the dimension `NB` is a runtime parameter. The memory pool allocator given as example in this library is only working with dimensions known at build time. For runtime dimensions, it is still using a `malloc`. 87 88