如何获得具有大对齐的块

How to obtain blocks with large alignment?

本文关键字:对齐 何获得      更新时间:2023-10-16

为了避免维护复杂的数据结构,我想分配对齐度相当大的块(比如一些千字节,可能是兆字节,总是2的幂)。这允许我屏蔽指针的低位,以便轻松检索它所指向的块的起始地址。

我想要一种方法来保证这样一个具有指定对齐的块的分配,例如,分配具有4096字节对齐的4096字节块。对于该方法,对齐将始终是块的大小,因此从长远来看,内存浪费预计将是一个问题。

我使用的是C++(所以C和C++技术很好),任何解决方案都应该可以在通用桌面环境中移植。若并没有可移植的解决方案,Linux的优先级最高。

我知道Win32内存分配有很大的一致性,但如果有一个通用的C库可以通过一个函数调用来实现这一点,我会很乐意使用它

背景:我正在试验那里描述的Vlist结构(最终目标是一种Scheme解释器),我目前正在为这些列表实现垃圾收集。我需要相当大的内存块作为垃圾收集器的竞技场。如果我改变GC技术,我仍然需要VList块进行32字节对齐(我正在64位机器上进行实验)。

我不知道有一个完全可移植的解决方案。但_mm_malloc()_mm_free()似乎得到了ICC、GCC和MSVC的支持。

这是作为对SSE内部函数的对齐内存支持的一部分添加的。


否则,您可以很容易地实现自己的

void* my_malloc(size_t bytes,size_t align){
    void *ptr = malloc(bytes + align + sizeof(intptr_t));
    if (ptr == NULL)
        return NULL;
    //  Get aligned return address
    intptr_t *ret = (intptr_t*)((((intptr_t)ptr + sizeof(intptr_t)) & ~(intptr_t)(align - 1)) + align);
    //  Save the free pointer
    ret[-1] = (intptr_t)ptr;
    return ret;
}
void my_free(void *ptr){
    if (ptr == NULL)
        return;
    //  Get the free pointer
    ptr = (void*)(((intptr_t*)ptr)[-1]);
    free(ptr); 
}

英特尔线程构建块有一个开源的跨平台可扩展内存分配器,支持对齐。

void* scalable_aligned_malloc(size_t size, size_t alignment);

在不使用系统调用的情况下,可移植的高效大对齐确实是可能的,在这种情况下,您可以围绕VirtualAllocmmap构建一个包装器,这将为您提供页面级对齐,通常为64kb。

但是,如果您只需要32个字节,只需从windowscrt复制源代码即可获得对齐的malloc和free,它由标准malloc支持,并且应该是完全可移植的(最好是glibc版本)。或者,您可以查看像nedmalloc 这样的自定义分配器