From f52d119b9c4f9b6dfbb91183de08143fdf3cc94c Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 3 Sep 2008 00:32:56 +0000 Subject: 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 data(10); will segfault if the vectorization is enabled, instead use: std::vector > data(10); NOTE: you only have to worry if you deal with fixed-size matrix types with "sizeof(matrix_type)%16==0"... --- test/dynalloc.cpp | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 test/dynalloc.cpp (limited to 'test/dynalloc.cpp') 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 +// +// 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 . + +#include "main.h" + +#include + +// 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 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() ); + CALL_SUBTEST( check_dynaligned() ); + CALL_SUBTEST( check_dynaligned() ); + CALL_SUBTEST( check_dynaligned() ); + CALL_SUBTEST( check_dynaligned() ); + } + + // 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; iavec.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; iavec.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 > vecs(N); + for (int j=0; j > foos(N); + for (int j=0; j