Re: [eigen] aliasing system |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
Benoit Jacob wrote:
On Thu, 6 Sep 2007, Andre Krause wrote:
Hi Andre,
I do understand your concern. Let me first stress that the same problem
exists in the other ET libraries. TVMET has a global function alias().
Blitz++ is even worse: not only does it suffer from the same problem, it
does not even provide an aliasing system! See here:
http://www.oonumerics.org/blitz/docs/blitz_3.html#SEC81
It would be impossible to determine exactly when aliasing is needed and
when it's not, without paying the price of a constant overhead, which we
don't want.
so then if there is no way to avoid this problem - what about a sort of
#pragma warning or assertion that gets thrown / printed in DEBUG mode
only, if a user tries to do
m = m*m;
is there some template magic available to detect this?
Expression templates eliminate temporaries. This is a big performance
improvement.
Let me try to explain what is going on here, because it really is
important. Here is an example. Suppose that you have vectors u, v, w,
and you do:
u = v + w;
Then Eigen2 will automatically evaluate this as:
for(int i = 0; i < size; i++) u[i] = v[i] + w[i];
and the for loop can then be unrolled (I'll take care of this later).
So this is fast.
Now Eigen1 (like any library without ETs) does this: it evaluates the
above expression as
operator=(u, operator+(v, w))
So it first calls operator+(v, w), which returns a result by value, so
call r this result, and then it calls operator=(u, r).
So all in all, Eigen1 evaluates this expression as:
for(int i = 0; i < size; i++) r[i] = v[i] + w[i];
for(int i = 0; i < size; i++) u[i] = r[i];
As you can see, Eigen1 is inefficient here, because it wastes time with
this useless temporary r. So the elimination of the temporary allows
Eigen2 to be much faster.
Thanks, this is a very nice example. though i had some cloudy idea about
temporaries already, this nails it down quite nice and clearly.
loop unrolling is totally clear for me, i did it with my own little
vector lib for 2,3 dim vectors and 3x3 and 4x4 matrices using partial
template specialisation.
Now alias() negates this. alias() forces the creation of a temporary. So
if we followed your suggestion of implementing operator= as
"this->alias() = m"
then we would negate much of the benefit of using expression templates!
We really want to only use alias() when it's necessary, because it is
costly.
I agree that it makes the API harder, but I don't see a better solution.
I think, this will be Item #1 in our FAQ/troubleshooting.
it shouldnt not only be #1 in the FAQ, but #1 in the very beginning of
an "about" or Introduction to Eigen2. You should explicitly write down
all cases that could be dangerous.
for example, what about
v = 2*v; // <-- doubling elements in a vector
are all expressions problematic, where the same variable name (here v)
is on both sides of the equation?
i am sure i COULD deduce by some or some more thinking wich equations
can be problematic, but it would be much easier to see a collection of
examples. and even better would be some compiler generated warning or
maybe some runtime warning ( in debug mode only ).
Cheers,
Benoit