- 1 WARNING!!! THE FOLLOWING IS A DRAFT OF PROPOSED FAQ ADDITIONS AND IS STILL UNDERGOING FACT CHECKING!
- 2 Memory Management
- 2.1 What actions trigger dynamic memory allocation?
- 2.2 When does storage get freed by Eigen?
- 2.3 Are there any common/subtle ways to accidentally leak memory in Eigen code?
- 2.4 Is there a way to check if I'm accidentally triggering dynamic memory allocation in a time critical block of code?
- 2.5 Do I ever need to worry about the storage cost of Matrix headers, and try to re-use them by messing around with pointers?
- 3 Array Storage Order (Row-Major vs. Column-Major)
WARNING!!! THE FOLLOWING IS A DRAFT OF PROPOSED FAQ ADDITIONS AND IS STILL UNDERGOING FACT CHECKING!
What actions trigger dynamic memory allocation?
- If the size of a MatrixXf isnt known at compile time, the only way to create it is on the heap:
MatrixXf x = MatrixXf::Zero(rows, cols);
- x.setZero(int, int) and friends, when the new size is greater or smaller than the old size.
- conservative resize functions, again only when the new size is greater or smaller than the old size.
- Temporary variables in expressions
Dynamic allocation only when their size is not known at compile time and not even a reasonable upper bound on their size is known at compile time. For example,
does not cause a malloc, since even though the size 'y' is not known at compile time, it is known that y<=4. In this case Eigen just reserves space for 4 scalars on the stack.
When does storage get freed by Eigen?
- Automatically whenever any dynamic array goes out of scope.
- Explicitly by the user by resizing an array to 0?
Are there any common/subtle ways to accidentally leak memory in Eigen code?
No, but it is recommended that you use a memory debugger to check your code anyways. Valgrind is recommended on UNIX systems.
Is there a way to check if I'm accidentally triggering dynamic memory allocation in a time critical block of code?
- If you define EIGEN_NO_MALLOC before #including Eigen headers, Eigen will crash on an assert failure whenever it was about to dynamically allocate memory.
- You could emit assembly code comments to delimit the section you care about, and look for malloc calls in between.
asm("#it begins here!") y = A*x + b asm("#it ends here!")
- valgrind can count and report the total number of times malloc gets called. You could comment out sections of your code and observe the effect on the global count.
- If you would like to implement a more clever solution, Memory.h is the place to start (search for EIGEN_NO_MALLOC).
Do I ever need to worry about the storage cost of Matrix headers, and try to re-use them by messing around with pointers?
- Dynamic size matrices contain only:
int rows, cols; Scalar *pointer; In almost all cases where a dynamic sized matrix would be used, this cost is insignificant compared to the size of the contained data.
- For most expressions, a good compiler will completely optimize away the templates, and even the above trivial cost will not be incurred.
Array Storage Order (Row-Major vs. Column-Major)
- Storage order can be specified on a per-matrix basis:
- It can also be specified as a global default, by adding the following before including the Eigen headers:
- Arrays of different storage can be mixed freely
- Eigen should write optimized code for both storage types, however:
- Some computations may be inherently faster if matrices are stored one way rather than another, i.e.:
- computing A*x for very tall A is slightly faster for (row?) major storage of A, and similarly:
- computing y*A for very wide A is slightly faster for (column?) major storage of A.