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

27 c c++ performance sse memory-alignment

这是我通常用于通过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

}
Run Code Online (Sandbox Code Playgroud)

这个代码一般是好的吗?我也见过人们用_mm_malloc,_mm_free.在大多数情况下,我想要对齐内存,使用SSE/AVX.我可以一般使用这些功能吗?它会使我的代码更简单.

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

此代码执行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;
Run Code Online (Sandbox Code Playgroud)

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

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

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

R..*_*R.. 11

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

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

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


Mat*_*son 5

您提出的第一个功能确实可以正常工作。

你的“homebrew”函数也可以工作,但有一个缺点,如果值已经对齐,你就浪费了 15 个字节。有时可能并不重要,但操作系统很可能能够提供正确分配的内存,而不会造成任何浪费(如果需要对齐到 256 或 4096 字节,则通过添加“alignment-1”可能会浪费大量内存字节)。

  • 如果编译器支持 _mm_malloc(),那么这也是一个有效的解决方案。您还需要使用“_mm_free()”。是的,当然,您可以使用 _mm_malloc() 进行任何内存分配 - 但当然,小分配会比“通常”浪费更多空间。 (2认同)