diff options
author | Gael Guennebaud <g.gael@free.fr> | 2008-09-03 00:32:56 +0000 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2008-09-03 00:32:56 +0000 |
commit | f52d119b9c4f9b6dfbb91183de08143fdf3cc94c (patch) | |
tree | 2369642bacec55b4d372797d42d27c74c6ac75eb /test/dynalloc.cpp | |
parent | d8df318d77b8a9bd9d6274f25145639603c2e8d4 (diff) |
Solve a big issue with data alignment and dynamic allocation:
* add a WithAlignedOperatorNew class with overloaded operator new
* make Matrix (and Quaternion, Transform, Hyperplane, etc.) use it
if needed such that "*(new Vector4) = xpr" does not failed anymore.
* Please: make sure your classes having fixed size Eigen's vector
or matrice attributes inherit WithAlignedOperatorNew
* add a ei_new_allocator STL memory allocator to use with STL containers.
This allocator really calls operator new on your types (unlike GCC's
new_allocator). Example:
std::vector<Vector4f> data(10);
will segfault if the vectorization is enabled, instead use:
std::vector<Vector4f,ei_new_allocator<Vector4f> > data(10);
NOTE: you only have to worry if you deal with fixed-size matrix types
with "sizeof(matrix_type)%16==0"...
Diffstat (limited to 'test/dynalloc.cpp')
-rw-r--r-- | test/dynalloc.cpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/test/dynalloc.cpp b/test/dynalloc.cpp new file mode 100644 index 000000000..287dce0d2 --- /dev/null +++ b/test/dynalloc.cpp @@ -0,0 +1,138 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see <http://www.gnu.org/licenses/>. + +#include "main.h" + +#include <ext/malloc_allocator.h> + +// test compilation with both a struct and a class... +struct MyStruct : WithAlignedOperatorNew +{ + char dummychar; + Vector4f avec; +}; + +class MyClassA : public WithAlignedOperatorNew +{ + public: + char dummychar; + Vector4f avec; +}; + +// ..as well as with some other base classes + +class MyBaseClass +{ + public: + char dummychar; + float afloat; +}; + +class MyClassB : public WithAlignedOperatorNew, public MyBaseClass +{ + public: + char dummychar; + Vector4f avec; +}; + +class MyClassC : public MyBaseClass, public WithAlignedOperatorNew +{ + public: + char dummychar; + Vector4f avec; +}; + +template<typename T> void check_dynaligned() +{ + T* obj = new T; + VERIFY(size_t(obj)%16==0); + delete obj; +} + +void test_dynalloc() +{ + +#ifdef EIGEN_VECTORIZE + for (int i=0; i<g_repeat*100; ++i) + { + CALL_SUBTEST( check_dynaligned<Vector4f>() ); + CALL_SUBTEST( check_dynaligned<Vector2d>() ); + CALL_SUBTEST( check_dynaligned<Matrix4f>() ); + CALL_SUBTEST( check_dynaligned<Vector4d>() ); + CALL_SUBTEST( check_dynaligned<Vector4i>() ); + } + + // check static allocation, who knows ? + { + MyStruct foo0; VERIFY(size_t(foo0.avec.data())%16==0); + MyClassA fooA; VERIFY(size_t(fooA.avec.data())%16==0); + MyClassB fooB; VERIFY(size_t(fooB.avec.data())%16==0); + MyClassC fooC; VERIFY(size_t(fooC.avec.data())%16==0); + } + + // dynamic allocation, single object + for (int i=0; i<g_repeat*100; ++i) + { + MyStruct *foo0 = new MyStruct(); VERIFY(size_t(foo0->avec.data())%16==0); + MyClassA *fooA = new MyClassA(); VERIFY(size_t(fooA->avec.data())%16==0); + MyClassB *fooB = new MyClassB(); VERIFY(size_t(fooB->avec.data())%16==0); + MyClassC *fooC = new MyClassC(); VERIFY(size_t(fooC->avec.data())%16==0); + delete foo0; + delete fooA; + delete fooB; + delete fooC; + } + + // dynamic allocation, array + const int N = 10; + for (int i=0; i<g_repeat*100; ++i) + { + MyStruct *foo0 = new MyStruct[N]; VERIFY(size_t(foo0->avec.data())%16==0); + MyClassA *fooA = new MyClassA[N]; VERIFY(size_t(fooA->avec.data())%16==0); + MyClassB *fooB = new MyClassB[N]; VERIFY(size_t(fooB->avec.data())%16==0); + MyClassC *fooC = new MyClassC[N]; VERIFY(size_t(fooC->avec.data())%16==0); + delete[] foo0; + delete[] fooA; + delete[] fooB; + delete[] fooC; + } + + // std::vector + for (int i=0; i<g_repeat*100; ++i) + { + std::vector<Vector4f, ei_new_allocator<Vector4f> > vecs(N); + for (int j=0; j<N; ++j) + { + VERIFY(size_t(vecs[j].data())%16==0); + } + std::vector<MyStruct,ei_new_allocator<MyStruct> > foos(N); + for (int j=0; j<N; ++j) + { + VERIFY(size_t(foos[j].avec.data())%16==0); + } + } + +#endif // EIGEN_VECTORIZE + +} |