Registered Member
|
Hello,
at the moment, we introduce Eigen into a project that formerly used primitive arrays for matrix/vector manipulation. While that decision was great in terms of readability, performance could not quite keep up. After profiling, I believe the following scenario to cause a heavy performance hit. We have a class that does some encapsulation around a MatrixXd, let's call it A. A provides a function getCol() that should return a certain column of the matrix values: Map<const VectorXd> A::getCol(int idx){ return Map<const VectorXd>(values.data()+offset+idx*size,size); } This function is efficient, as soon as the vector is directly manipulated - omit the constness shortly and consider: Map<VectorXd> col = A::getCol(4); col[0] = 24; ==> That is not slower that primitive arrays. However, this column is then used differently, like this: MatrixXd B; MatrixXd C; VectorXd v; ///// v = A.getCol(i)-A.getCol(j); C = B * v; /////// where the last two lines are called very often and therefore need to be efficient. When profiling the function with this statement, I see memory allocation and deallocation that was not there in the former, primitive version that looks something like this: double* v; double** B; double** C; v = minus(A.getCol(i), A.getCol(j), /*...*/); C = times(B, v, /*...*/); It looks to me, that in the version using Eigen, temporaries or copies are created, although there is no need for them - or there is some type-casting going on. Is that right and if so, how can I speed up that part? To make my use case more clear: I think an array of VectorXd would suit my needs best, where getCol would be implemented like: const VectorXd& A::getCol(int idx){ return values.at(offset+idx); } - but if feels wrong to me not to use a matrix when I want to store a bunch of column vectors. Strangely enough (this might be a different issue), rewriting the expression as follows is even slower - why is this? C = B * (A.getCol(i)-A.getCol(j)); |
Registered Member
|
Hello,
I got news on my problem. I am convinced that an implicit cast Map<VectorXd> -> VectorXd makes the program slow. Consider the following test case:
Here, the primitive version is two times faster than eigen. If you however, change the signature of the second workOnCon-function, which is called by tc_slow, to
the functions perform similar. |
Moderator
|
I did not read the entire message, so sorry if I'm off and ping me if I missed something important, but if want to accept both a VectorXd, a column of a MatrixXd or a Map<VectorXd>, then declare the argument with Ref<const VectorXd>:
void foo(Ref<const VectorXd> vec) { /* do something with vec */} See the respective doc for further details. |
Registered users: Bing [Bot], blue_bullet, Google [Bot], rockscient, Yahoo [Bot]