* implement handmade aligned malloc, fast but always wastes 16 bytes of memory.

only used as fallback for now, needs benchmarking.
  also notice that some malloc() impls do waste memory to keep track of alignment
  and other stuff (check msdn's page on malloc).
* expand test_dynalloc to cover low level aligned alloc funcs. Remove the old
  #ifdef EIGEN_VECTORIZE...
* rewrite the logic choosing an aligned alloc, some new stuff:
  * malloc() already aligned on freebsd and windows x64 (plus apple already)
  * _mm_malloc() used only if EIGEN_VECTORIZE
  * posix_memalign: correct detection according to man page (not necessarily
    linux specific), don't attempt to declare it if the platform didn't declare it
    (there had to be a reason why it didn't declare it, right?)
This commit is contained in:
Benoit Jacob
2009-01-09 14:56:44 +00:00
parent f52a9e5315
commit fd831d5a12
2 changed files with 101 additions and 15 deletions

View File

@@ -24,6 +24,55 @@
#include "main.h"
void check_handmade_aligned_malloc()
{
for(int i = 1; i < 1000; i++)
{
char *p = (char*)ei_handmade_aligned_malloc(i);
VERIFY(size_t(p)%16==0);
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
for(int j = 0; j < i; j++) p[j]=0;
ei_handmade_aligned_free(p);
}
}
void check_aligned_malloc()
{
for(int i = 1; i < 1000; i++)
{
char *p = (char*)ei_aligned_malloc(i);
VERIFY(size_t(p)%16==0);
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
for(int j = 0; j < i; j++) p[j]=0;
ei_aligned_free(p);
}
}
void check_aligned_new()
{
for(int i = 1; i < 1000; i++)
{
float *p = ei_aligned_new<float>(i);
VERIFY(size_t(p)%16==0);
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
for(int j = 0; j < i; j++) p[j]=0;
ei_aligned_delete(p,i);
}
}
void check_aligned_stack_alloc()
{
for(int i = 1; i < 1000; i++)
{
float *p = ei_aligned_stack_new(float,i);
VERIFY(size_t(p)%16==0);
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
for(int j = 0; j < i; j++) p[j]=0;
ei_aligned_stack_delete(float,p,i);
}
}
// test compilation with both a struct and a class...
struct MyStruct
{
@@ -49,8 +98,12 @@ template<typename T> void check_dynaligned()
void test_dynalloc()
{
// low level dynamic memory allocation
CALL_SUBTEST(check_handmade_aligned_malloc());
CALL_SUBTEST(check_aligned_malloc());
CALL_SUBTEST(check_aligned_new());
CALL_SUBTEST(check_aligned_stack_alloc());
#ifdef EIGEN_VECTORIZE
for (int i=0; i<g_repeat*100; ++i)
{
CALL_SUBTEST( check_dynaligned<Vector4f>() );
@@ -100,6 +153,4 @@ void test_dynalloc()
}
}
#endif // EIGEN_VECTORIZE
}