This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Suitability of Eigen for hard realtime tasks

Tags: None
(comma "," separated)
diegoboesel
Registered Member
Posts
2
Karma
0
Hello,

I am developing an application in C++ to control an industrial robot arm motion. The thread controlling the robot arm needs to perfom some calculations (matrices, up to dimension 6x6, multiplication and inversion as well as some quaternions operations) to which I would like to use Eigen. This thread is hard realtime and it should not miss deadlines of the task scheduller.

I wonder whether the Eigen is suitable for this application. My point is that I read that eigen creates objects and allocates memory, which should not be the case in such application. Is it possible to _completely_ avoid it? Is there a drawback to the computation performance when avoiding it?

Thanks
Diego
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Yes Eigen can avoid memory allocation when you use fixed-size scalar types. The objects will be statically allocated on the stack. E.g.
Code: Select all
Matrix<float,6,6> A;
Matrix<float,6,1> x, b;
x = A.lu().solve(b);


The last line will create one 6x6 matrix plus one 6x1 vector on the stack. You can even create a matrix decomposition once and reuse it several times:
Code: Select all
PartialPivLU<Matrix<float,6,6> > lu;
// ...
lu.compute(A);
x = lu.solve(b);


You can also #define EIGEN_NO_MALLOC before including any Eigen's header to make sure malloc or the likes will never be called (it raises an assert if so, good for debugging).

Finally, if your matrices have varying sizes up to 6x6, then you can declare them as:

typedef Matrix<float,Dynamic,Dynamic,0,6,6> Mat;

It will behave like a MatrixXf but with static allocation and matrix sizes limited to 6x6.
aheller
Registered Member
Posts
2
Karma
0
I am using fixed-size types, but wether or not memory allocation uccurs seems to depend on the size of the matrix:

Code: Select all
#define EIGEN_RUNTIME_NO_MALLOC // Define this symbol to enable runtime tests for allocations
#include <Eigen/Dense>
using namespace Eigen;

#include <iostream>
#include <complex>
using namespace std;

template<int N>
void test()
{
   Matrix<complex<float>,N,N> A;
   Matrix<complex<float>,N,1> b;
   Matrix<complex<float>,N,1> x;
   PartialPivLU<Matrix<complex<float>,N,N> > lu;
   A = A.Random();
   b = b.Random();
   // allow lu to create temporaries for the first call if required
   lu.compute(A);
   x = lu.solve(b);
   internal::set_is_malloc_allowed(true);
   // in the second call I'd expect no allocs
   lu.compute(A);
   x = lu.solve(b);
   internal::set_is_malloc_allowed(false);
   cout << x << endl; // just for using x
}

int main()
{
   test<10>();
   test<50>(); // assert
   return 0;
}


The allocation occurs in triangular_solve_matrix where temporaries are generated:
Code: Select all
    ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
    ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
    ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW());


But as the name indicates, these should be on the stack, right?

Is there a way to avoid these mallocs?
From the source, I see that this behavior could probably changed with EIGEN_STACK_ALLOCATION_LIMIT; Is it ok to modify this?
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Does your system support alloca? If so compiling with -DEIGEN_ALLOCA=alloca should workaround the issue. Currently alloca is enabled by default on Linux or with MSVC only.
aheller
Registered Member
Posts
2
Karma
0
ok, thanks, that worked.
The environment is mingw, which obviously supports alloca (gcc).
Under Linux I don't need the define, as expected.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
For the record, there is a related bug entry: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=729


Bookmarks



Who is online

Registered users: Baidu [Spider], Bing [Bot], Google [Bot], Yahoo [Bot]