是否有与_aligned_realloc等效的Linux [英] Is there a linux equivalent of _aligned_realloc

查看:47
本文介绍了是否有与_aligned_realloc等效的Linux的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否存在 _ aligned_realloc ?

我想使用realloc,所以我不必每次调整大小时都对数据进行存储.我会被mmap卡住吗?我仅使用mmap一次,有没有建议的实现内存大小的方法,该方法将被调整几次?我假设我不能将mmap与aligned_alloc混合使用,并且在第一次调整大小时必须做memcpy吗?(或始终使用mmap)

I want to use realloc so I don't have to memcpy the data every time I resize it. Am I stuck with mmap? I only used mmap once is there a recommended way of implementing memory that will be resized a few times? I'm assuming I can't mix mmap with aligned_alloc and I would have to do memcpy for the first resize? (or always use mmap)

下面的realloc并不总是对齐的.我使用gcc和clang在(64bit)linux下进行了测试

The realloc below doesn't always align. I tested under (64bit) linux using gcc and clang

#include<cstdlib>
#include<cstdio>
#define ALIGNSIZE 64
int main()
{
    for(int i = 0; i<10; i++)
    {
        void *p = aligned_alloc(ALIGNSIZE, 4096);
        void *p2 = realloc(p, 4096+2048); //This doesn't always align
        //void *p3 = aligned_alloc(ALIGNSIZE, 4096/24); //Doesn't need this line to make it unaligned. 

        if (((long)p & (ALIGNSIZE-1)) != 0 || ((long)p2 & (ALIGNSIZE-1)) != 0)
            printf("%d %d %d\n", i, ((long)p & (ALIGNSIZE-1)) != 0, ((long)p2 & (ALIGNSIZE-1)) != 0);
    }
}

推荐答案

不,C ++,POSIX标准和GNU C库中都没有标准替代品.

No, there is neither standard alternative in C++, nor in POSIX standard, nor in the GNU C library.

这里是仅使用标准功能的概念证明:

Here is a proof of concept using only standard functions:

void*
aligned_realloc_optimistic(
    void* ptr, std::size_t new_size, std::size_t alignment)
{
    void* reallocated = std::realloc(ptr, new_size);
    return is_aligned(reallocated, alignment) // see below
        ? reallocated
        : aligned_realloc_pessimistic(reallocated, new_size, new_size, alignment);
        // see below
}

如评论中所指出:有一个警告,在最坏的情况下, std :: realloc 可能无法重用分配,并且碰巧返回未对齐的指针,然后我们分配两次.

As pointed out in the comments: This has the caveat that in the worst case std::realloc may fail to reuse the allcation and also happens to return an misaligned pointer, then we allocate twice.

我们可以通过无条件分配,复制和释放来跳过重新分配的尝试,从而消除了双重分配的最坏情况和无分配的最好情况:

We can skip attempting to realloc by just unconditionally allocting, copying and freeing which removes both the worst case of double allocation and the best case of no allocation:

void*
aligned_realloc_pessimistic(
    void* ptr, std::size_t new_size, std::size_t old_size, std::size_t alignment)
{
    void* aligned = std::aligned_alloc(alignment, new_size);
    std::memcpy(aligned, ptr, old_size);
    std::free(ptr);
    return aligned;
}

一个明显的问题是,我们必须知道常规重新分配不需要的旧大小.

The obvious problem with this is that we have to know the old size which is was not required with the regular reallocation.

依靠系统特定的功能,我们可以保持避免分配和避免重复分配的最佳情况,也不需要知道旧的大小:

By relying on system specific functions, we can keep the optimal case of avoiding allocation and avoid double allocation and also not require knowing the old size:

void*
aligned_realloc_glibc(
    void* ptr, std::size_t new_size, std::size_t alignment)
{
    auto old_size = malloc_usable_size(ptr); // GNU extension
    return old_size >= new_size && is_aligned(ptr, alignment)
        ? ptr
        : aligned_realloc_pessimistic(ptr, new_size, old_size, alignment);
}

上面使用的辅助功能:

bool is_aligned(void* ptr, std::size_t alignment)
{
    std::size_t space = 1;
    return std::align(alignment, space, ptr, space);
}

这篇关于是否有与_aligned_realloc等效的Linux的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆