获得对齐内存的最佳跨平台方法

这是我通常使用的代码,用于获取与Visual Studio和GCC对齐的内存

inline void* aligned_malloc(size_t size, size_t align) { void *result; #ifdef _MSC_VER result = _aligned_malloc(size, align); #else if(posix_memalign(&result, align, size)) result = 0; #endif return result; } inline void aligned_free(void *ptr) { #ifdef _MSC_VER _aligned_free(ptr); #else free(ptr); #endif } 

这个代码一般都没问题吗? 我也看到人们使用_mm_malloc_mm_free 。 在大多数情况下,我想要对齐内存,使用SSE / AVX。 我可以一般使用这些function吗? 它会使我的代码更简单。

最后,创建我自己的函数来对齐内存很容易(见下文)。 那么为什么有这么多不同的常用函数来获得对齐的内存(其中许多只能在一个平台上运行)?

此代码执行16字节对齐。

 float* array = (float*)malloc(SIZE*sizeof(float)+15); // find the aligned position // and use this pointer to read or write data into array float* alignedArray = (float*)(((unsigned long)array + 15) & (~0x0F)); // dellocate memory original "array", NOT alignedArray free(array); array = alignedArray = 0; 

请参阅: http : //www.songho.ca/misc/alignment/dataalign.html以及如何仅使用标准库分配对齐的内存?

编辑:如果有人关心,我从Eigen(Eigen / src / Core / util / Memory.h)得到了我的aligned_malloc()函数的想法

编辑:我刚刚发现,MinGW未定义posix_memalign 。 但是, _mm_malloc适用于Visual Studio 2012,GCC,MinGW和Intel C ++编译器,因此它似乎是最方便的解决方案。 它还需要使用自己的_mm_free函数,尽管在某些实现中,您可以将指针从_mm_malloc传递给标准的free / delete

你提出的第一个function确实可以正常工作。

你的“自制”function也有效,但缺点是如果值已经对齐,你就浪费了15个字节。 有时可能无关紧要,但OS可能能够提供正确分配而没有任何浪费的内存(如果需要将其对齐到256或4096字节,则可能会因添加“alignment-1”而浪费大量内存)字节)。

只要您可以通过调用特殊function来执行释放,您的方法就可以了。 我会以相反的方式做你的#ifdef :从标准指定的选项开始,然后回到平台特定的选项。 例如

  1. 如果__STDC_VERSION__ >= 201112L使用aligned_alloc
  2. 如果_POSIX_VERSION >= 200112L使用posix_memalign
  3. 如果定义了_MSC_VER ,请使用Windows内容。
  4. 如果所有其他方法都失败了,只需使用malloc / free并禁用SSE / AVX代码。

如果你想将分配的指针传递给free ,问题就更难了; 这在所有标准接口上都有效,但在Windows上没有,并且不一定与某些类似unix的系统具有传统的memalignfunction。

这是一个固定的user2093113的示例,直接代码没有为我构建(void * unknown size)。 我还把它放在模板类中,覆盖operator new / delete,这样你就不必进行新的分配和调用。

 #include  template class Aligned { public: void* operator new(std::size_t size) { std::size_t space = size + (Alignment - 1); void *ptr = malloc(space + sizeof(void*)); void *original_ptr = ptr; char *ptr_bytes = static_cast(ptr); ptr_bytes += sizeof(void*); ptr = static_cast(ptr_bytes); ptr = std::align(Alignment, size, ptr, space); ptr_bytes = static_cast(ptr); ptr_bytes -= sizeof(void*); std::memcpy(ptr_bytes, &original_ptr, sizeof(void*)); return ptr; } void operator delete(void* ptr) { char *ptr_bytes = static_cast(ptr); ptr_bytes -= sizeof(void*); void *original_ptr; std::memcpy(&original_ptr, ptr_bytes, sizeof(void*)); std::free(original_ptr); } }; 

像这样用它:

 class Camera : public Aligned<16> { }; 

尚未测试此代码的跨平台性。

如果编译器支持它,C ++ 11会添加一个std::align函数来进行运行时指针对齐。 您可以像这样实现自己的malloc / free(未经测试):

 template void *aligned_malloc(std::size_t size) { std::size_t space = size + (Align - 1); void *ptr = malloc(space + sizeof(void*)); void *original_ptr = ptr; char *ptr_bytes = static_cast(ptr); ptr_bytes += sizeof(void*); ptr = static_cast(ptr_bytes); ptr = std::align(Align, size, ptr, space); ptr_bytes = static_cast(ptr); ptr_bytes -= sizeof(void*); std::memcpy(ptr_bytes, original_ptr, sizeof(void*)); return ptr; } void aligned_free(void* ptr) { void *ptr_bytes = static_cast(ptr); ptr_bytes -= sizeof(void*); void *original_ptr; std::memcpy(&original_ptr, ptr_bytes, sizeof(void*)); std::free(original_ptr); } 

然后你不必保持原始指针值来释放它。 这是100%便携式我不确定,但我希望有人会纠正我,如果不是!

这是我的2美分:

 temp = new unsigned char*[num]; AlignedBuffers = new unsigned char*[num]; for (int i = 0; i((reinterpret_cast (temp[i% num]) + 15) & ~15);// 16 bit alignment in preperation for SSE }