Talk:FAQ

From Eigen
Revision as of 04:51, 3 May 2010 by Drewm1980 (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

WARNING!!! THE FOLLOWING IS A DRAFT OF PROPOSED FAQ ADDITIONS AND IS STILL UNDERGOING FACT CHECKING!

Memory Management

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,

Vector4d.segment(x,y).eval()

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:
Matrix<float,Dynamic,Dynamic,RowMajor> my_rowmaj_matrix;
  • It can also be specified as a global default, by adding the following before including the Eigen headers:
#define EIGEN_DEFAULT_TO_ROW_MAJOR
  • 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.