获取对齐内存块有几种选择,但它们非常相似,问题主要在于您所针对的语言标准和平台。
C11
void * aligned_alloc (size_t alignment, size_t size)
POSIX
int posix_memalign (void **memptr, size_t alignment, size_t size)
视窗
void * _aligned_malloc(size_t size, size_t alignment);
当然,用手对齐也是一种选择。
英特尔提供了另一种选择。
英特尔
void* _mm_malloc (int size, int align)
void _mm_free (void *p)
基于Intel发布的源代码,这似乎是他们工程师喜欢的分配对齐内存的方法,但我找不到任何与其他方法相比较的文档。我发现的最接近的只是承认存在其他对齐内存分配例程。
要动态分配对齐内存,请使用由GCC和英特尔编译器支持的posix_memalign。使用它的好处是您不必更改内存处理API。您可以像往常一样使用free()。但是,请注意参数简介: posix_memalign ( **memptr,size_t对齐,size_t大小); Intel编译器还提供了另一组内存分配API。C/C++程序员可以使用_mm_malloc和_mm_free分配和释放对齐内存块。例如,以下语句为8个浮点元素请求一个64字节对齐内存块. __mm_malloc(8*sizeof( ),64); 使用_mm_malloc分配的内存必须使用_mm_free释放。在用_mm_malloc分配的内存上调用空闲或对使用malloc分配的内存调用_mm_free将导致不可预测的行为。
从用户的角度看,_mm_malloc
需要直接的CPU和编译器支持,_mm_malloc
分配的内存必须用_mm_free
释放。鉴于这些缺点,使用_mm_malloc?
的原因是什么?它是否具有轻微的性能优势?历史上的意外?
发布于 2015-09-20 03:00:18
Intel编译器支持POSIX (Linux)和非POSIX ( Windows )操作系统,因此不能依赖POSIX或Windows功能。因此,选择了一个特定于编译器但与操作系统无关的解决方案。
C11是一个很好的解决方案,但是微软甚至还不支持C99,所以谁知道他们是否会支持C11。
更新:与C11/POSIX/分配函数不同,本质上包含一个去分配函数。这允许此API使用独立的堆管理器,而不是默认的堆管理器。我不知道它是否/什么时候真正做到了这一点,但是支持这个模型可能是有用的。
免责声明:我为英特尔工作,但对这些决定没有特别的了解,这发生在我加入公司之前很久。
发布于 2015-09-16 15:58:08
可以使用现有的C编译器,该编译器目前不碰巧使用标识符_mm_alloc
和_mm_free
,并使用需要的名称定义函数。这可以通过让_mm_alloc
函数作为malloc()
上的包装器来实现,它要求一个稍微过大的分配,并在其中构造一个指向第一个适当对齐地址的指针--从一开始至少有一个字节,并存储在该地址之前跳过的字节数,或者让_mm_malloc
从malloc()
请求大量内存块,然后分片分配它们。在任何情况下,_mm_malloc()
返回的指针都不是free()
通常知道如何处理的指针;调用_mm_free
将使用分配之前的字节来帮助查找从malloc
收到的分配的真正开始,然后传递给执行free
的指针。
但是,如果允许对齐分配函数使用malloc
和free
函数的内部,则可能不需要额外的包装层。可以编写包装_mm_alloc()
/free
的malloc
/free
函数,而不知道它们的内部结构,但它要求_mm_alloc()
保存与malloc
/free
所使用的独立的簿记信息。
如果对齐分配函数的作者知道malloc
和free
是如何实现的,那么通常可以协调所有分配/空闲函数的设计,以便free
能够区分各种分配并适当地处理它们。然而,在所有malloc
/free
实现上,没有一个对齐的分配实现是可用的。
我建议编写代码的最可移植的方式可能是选择两个符号,这些符号在其他任何地方都不会用于您自己的分配和空闲函数,这样您就可以这样说。
#define a_alloc(align,sz) _mm_alloc((align),(sz))
#define a_free(ptr) _mm_free((ptr))
的编译器上,或者
static inline void *aa_alloc(int align, int size)
{
void *ret=0;
posix_memalign(&ret, align, size); // Guessing here
return ret;
}
#define a_alloc(align,sz) aa_alloc((align),(sz))
#define a_free(ptr) free((ptr))
在Posix系统等方面,对于每个系统来说,应该有可能定义将产生必要行为的宏或函数,我认为,与有时使用宏和有时使用函数相比,使用宏可能更好,以便允许#if defined macroname
测试是否定义了事物。
发布于 2015-09-16 15:44:27
_mm_malloc似乎是在标准aligned_alloc函数出现之前创建的,使用_mm_free的需求是实现的一个怪癖。
我的猜测是,与使用posix_memalign不同的是,它不需要为了保证对齐而过度分配,而是使用单独的对齐感知分配器。这将在分配与默认对齐方式不同的类型(通常为8或16字节)时节省内存。
https://stackoverflow.com/questions/32612881
复制相似问题