2

http://www.alex-ionescu.com/?p=50

我读了上面的帖子。作者通过单链表示例解释了为什么 Windows x64 只支持 44 位虚拟内存地址。

struct {  // 8-byte header
        ULONGLONG Depth:16;
        ULONGLONG Sequence:9;
        ULONGLONG NextEntry:39;
} Header8;

首先要做的牺牲是将序列号的空间减少到 9 位而不是 16 位,从而减少列表可以实现的最大序列号。这仍然只为指针留下了 39 位——对 32 位的改进是平庸的。通过在分配时强制结构为 16 字节对齐,可以再赢得 4 位,因为现在可以始终假定底部位为 0。


哦,我无法理解。

什么“通过在分配时强制结构为 16 字节对齐,可以再赢得 4 位,因为现在可以始终假定底部位为 0。” 方法?

4

2 回答 2

3
16 is 0010000 in binary

32 is 0100000 in binary

64 is 1000000 in binary

ETC

您可以看到,对于所有 16 的倍数的数字,最后四位始终为零。因此,您可以不用存储这些位,而是在需要使用指针时将它们添加回来。

于 2010-12-30T14:23:56.500 回答
2

对于一个 2^N 字节对齐的指针,它的地址总是可以被 2^N 整除——这意味着低 N 位总是为零。您可以在其中存储其他信息:

encode ptr payload = ptr | payload
decode_ptr data = data & ~mask
decode_payload data = data & mask

其中 mask 是(1 << N) - 1- 即设置了低 N 位的数字。

这个技巧通常用于在低级代码中节省空间(有效负载可以是 GC 标志、类型标记等)

实际上,您存储的不是指针,而是可以从中提取指针的数字。当然,应注意不要在未解码的情况下将数字取消引用为指针。

于 2010-12-30T14:23:17.070 回答