为什么在实现对齐的malloc时使用位运算符&和〜而不是数学运算符%?

问题描述 投票:1回答:1

[在研究Linux操作系统的内存管理时,我看到实现对齐的malloc函数的一般解决方案是以下代码:

void* aligned_malloc(size_t required_bytes, size_t alignment)
{
    void* p1; // original block
    void** p2; // aligned block
    int offset = alignment - 1 + sizeof(void*);
    if ((p1 = (void*)malloc(required_bytes + offset)) == NULL)
    {
       return NULL;
    }
    p2 = (void**)(((size_t)(p1) + offset) & ~(alignment - 1));
    p2[-1] = p1;
    return p2;
}

此解决方案的问题是,由于alignment,仅当& ~(alignment - 1)为2的幂时,它才能正常工作。此外,alignment必须是size_t数据类型,以便适合指针p1的数据类型。由于这些限制,我想到了另一种解决方案:

void* aligned_malloc(size_t required_bytes, size_t alignment)
{
    void* p1; // original block
    void** p2; // aligned block
    int offset = alignment - 1 + sizeof(void*);
    if ((p1 = (void*)malloc(required_bytes + offset)) == NULL)
    {
        return NULL;
    }
    offset = (size_t)(p1) % alignment; // offset is used so that I don't have to declare another variable
    p2 = (void**)((size_t)(p1) + (alignment - offset));
    p2[-1] = p1;
    return p2;
}

此解决方案解决了两个问题,即alignment不必既不是2的幂,也不是size_t数据类型。我的问题是,为什么不使用这种方式来实现对齐的malloc?使人们选择按位运算符&~代替解决方案的缺点是什么?

非常感谢您的帮助。谢谢。

c linux memory-management malloc
1个回答
2
投票

可能是因为alignment是一个变量(对于编译器而言)是未知值,这意味着编译器无法通过简单的操作轻松实现它。

按位运算比%运算符所需的算术(尤其是除法)更简单,更高效。

© www.soinside.com 2019 - 2024. All rights reserved.