首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内存对齐公式

内存对齐公式
EN

Stack Overflow用户
提问于 2017-07-20 11:33:28
回答 1查看 2.3K关注 0票数 5

在浏览一些内核代码时,我发现了一个内存对齐公式,如

对齐=((操作数+(对齐- 1))和~(对齐- 1))

所以我甚至为此写了一个程序:

代码语言:javascript
复制
#include <stdio.h>

int main(int argc, char** argv) {
    long long operand;
    long long alignment;
    if(argv[1]) {
        operand = atol(argv[1]);
    } else {
        printf("Enter value to be aligned!\n");
        return -1;
    }
    if(argv[2]) {
        alignment = strtol(argv[2],NULL,16);
    } else {
        printf("\nDefaulting to 1MB alignment\n");
        alignment = 0x100000;
    }
    long long aligned = ((operand + (alignment - 1)) & ~(alignment - 1));
    printf("Aligned memory is: 0x%.8llx [Hex] <--> %lld\n",aligned,aligned);
    return 0;
}

但我一点也不明白这个逻辑。这是怎么回事?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-20 11:39:57

基本上,公式将整数operand (地址)增加到与alignment对齐的下一个地址。

表达式

代码语言:javascript
复制
aligned = ((operand + (alignment - 1)) & ~(alignment - 1))

基本上与更容易理解的公式相同:

代码语言:javascript
复制
aligned = int((operand + (alignment - 1)) / alignment) * alignment

例如,有操作数(地址) 102和对齐10,我们得到:

代码语言:javascript
复制
aligned = int((102 + 9) / 10) * 10
aligned = int(111 / 10) * 10
aligned = 11 * 10
aligned = 110

首先,我们添加到address 9并获取111。然后,因为我们的对齐是10,基本上我们把最后一个数字,也就是111 / 10 * 10 = 110

请注意,对于10对齐的每一次幂(即10,100,1000等),我们基本上将最后一位数归零。

在大多数CPU上,除法和乘法运算比按位运算花费的时间要长得多,所以让我们回到原来的公式:

代码语言:javascript
复制
aligned = ((operand + (alignment - 1)) & ~(alignment - 1))

公式的第二部分只有在对齐为2的幂时才有意义。例如:

代码语言:javascript
复制
... & ~(2 - 1) will zero last bit of address.
... & ~(64 - 1) will zero last 5 bits of address.
etc

就像将地址的最后几位数归零表示10次对齐一样,我们将最后几位位归零为2位对齐。

希望这对你来说有意义。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45213511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档