dynalloc.cpp (4760B)
1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 #include "main.h" 11 12 #if EIGEN_MAX_ALIGN_BYTES>0 13 #define ALIGNMENT EIGEN_MAX_ALIGN_BYTES 14 #else 15 #define ALIGNMENT 1 16 #endif 17 18 typedef Matrix<float,16,1> Vector16f; 19 typedef Matrix<float,8,1> Vector8f; 20 21 void check_handmade_aligned_malloc() 22 { 23 for(int i = 1; i < 1000; i++) 24 { 25 char *p = (char*)internal::handmade_aligned_malloc(i); 26 VERIFY(internal::UIntPtr(p)%ALIGNMENT==0); 27 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind 28 for(int j = 0; j < i; j++) p[j]=0; 29 internal::handmade_aligned_free(p); 30 } 31 } 32 33 void check_aligned_malloc() 34 { 35 for(int i = ALIGNMENT; i < 1000; i++) 36 { 37 char *p = (char*)internal::aligned_malloc(i); 38 VERIFY(internal::UIntPtr(p)%ALIGNMENT==0); 39 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind 40 for(int j = 0; j < i; j++) p[j]=0; 41 internal::aligned_free(p); 42 } 43 } 44 45 void check_aligned_new() 46 { 47 for(int i = ALIGNMENT; i < 1000; i++) 48 { 49 float *p = internal::aligned_new<float>(i); 50 VERIFY(internal::UIntPtr(p)%ALIGNMENT==0); 51 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind 52 for(int j = 0; j < i; j++) p[j]=0; 53 internal::aligned_delete(p,i); 54 } 55 } 56 57 void check_aligned_stack_alloc() 58 { 59 for(int i = ALIGNMENT; i < 400; i++) 60 { 61 ei_declare_aligned_stack_constructed_variable(float,p,i,0); 62 VERIFY(internal::UIntPtr(p)%ALIGNMENT==0); 63 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind 64 for(int j = 0; j < i; j++) p[j]=0; 65 } 66 } 67 68 69 // test compilation with both a struct and a class... 70 struct MyStruct 71 { 72 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 73 char dummychar; 74 Vector16f avec; 75 }; 76 77 class MyClassA 78 { 79 public: 80 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 81 char dummychar; 82 Vector16f avec; 83 }; 84 85 template<typename T> void check_dynaligned() 86 { 87 // TODO have to be updated once we support multiple alignment values 88 if(T::SizeAtCompileTime % ALIGNMENT == 0) 89 { 90 T* obj = new T; 91 VERIFY(T::NeedsToAlign==1); 92 VERIFY(internal::UIntPtr(obj)%ALIGNMENT==0); 93 delete obj; 94 } 95 } 96 97 template<typename T> void check_custom_new_delete() 98 { 99 { 100 T* t = new T; 101 delete t; 102 } 103 104 { 105 std::size_t N = internal::random<std::size_t>(1,10); 106 T* t = new T[N]; 107 delete[] t; 108 } 109 110 #if EIGEN_MAX_ALIGN_BYTES>0 && (!EIGEN_HAS_CXX17_OVERALIGN) 111 { 112 T* t = static_cast<T *>((T::operator new)(sizeof(T))); 113 (T::operator delete)(t, sizeof(T)); 114 } 115 116 { 117 T* t = static_cast<T *>((T::operator new)(sizeof(T))); 118 (T::operator delete)(t); 119 } 120 #endif 121 } 122 123 EIGEN_DECLARE_TEST(dynalloc) 124 { 125 // low level dynamic memory allocation 126 CALL_SUBTEST(check_handmade_aligned_malloc()); 127 CALL_SUBTEST(check_aligned_malloc()); 128 CALL_SUBTEST(check_aligned_new()); 129 CALL_SUBTEST(check_aligned_stack_alloc()); 130 131 for (int i=0; i<g_repeat*100; ++i) 132 { 133 CALL_SUBTEST( check_custom_new_delete<Vector4f>() ); 134 CALL_SUBTEST( check_custom_new_delete<Vector2f>() ); 135 CALL_SUBTEST( check_custom_new_delete<Matrix4f>() ); 136 CALL_SUBTEST( check_custom_new_delete<MatrixXi>() ); 137 } 138 139 // check static allocation, who knows ? 140 #if EIGEN_MAX_STATIC_ALIGN_BYTES 141 for (int i=0; i<g_repeat*100; ++i) 142 { 143 CALL_SUBTEST(check_dynaligned<Vector4f>() ); 144 CALL_SUBTEST(check_dynaligned<Vector2d>() ); 145 CALL_SUBTEST(check_dynaligned<Matrix4f>() ); 146 CALL_SUBTEST(check_dynaligned<Vector4d>() ); 147 CALL_SUBTEST(check_dynaligned<Vector4i>() ); 148 CALL_SUBTEST(check_dynaligned<Vector8f>() ); 149 CALL_SUBTEST(check_dynaligned<Vector16f>() ); 150 } 151 152 { 153 MyStruct foo0; VERIFY(internal::UIntPtr(foo0.avec.data())%ALIGNMENT==0); 154 MyClassA fooA; VERIFY(internal::UIntPtr(fooA.avec.data())%ALIGNMENT==0); 155 } 156 157 // dynamic allocation, single object 158 for (int i=0; i<g_repeat*100; ++i) 159 { 160 MyStruct *foo0 = new MyStruct(); VERIFY(internal::UIntPtr(foo0->avec.data())%ALIGNMENT==0); 161 MyClassA *fooA = new MyClassA(); VERIFY(internal::UIntPtr(fooA->avec.data())%ALIGNMENT==0); 162 delete foo0; 163 delete fooA; 164 } 165 166 // dynamic allocation, array 167 const int N = 10; 168 for (int i=0; i<g_repeat*100; ++i) 169 { 170 MyStruct *foo0 = new MyStruct[N]; VERIFY(internal::UIntPtr(foo0->avec.data())%ALIGNMENT==0); 171 MyClassA *fooA = new MyClassA[N]; VERIFY(internal::UIntPtr(fooA->avec.data())%ALIGNMENT==0); 172 delete[] foo0; 173 delete[] fooA; 174 } 175 #endif 176 177 }