究竟什么是“位填充”或“填充位”?

Rob*_*rtS 1 c c++ memory memory-management padding

我不想用这个来骚扰你,但我在互联网上的任何地方都找不到关于“位填充”究竟是什么的详细解释,以及 StackOverflow 上与位填充相关的线程的任何答案.

我还搜索了 ISO 9899-1990,其中提到了“位填充”,但在我需要时并未对其进行解释。

我在网上找到的关于此的唯一内容是here,其中只给出了对一句话的一个可笑的简短解释,说:

位填充:

位填充是向传输或存储单元添加一个或多个额外位以使其符合标准大小。

一些来源将位填充识别为一种 位填充

其中至少有某种信息,但对我来说还不够解释。我不太明白这到底是什么意思。它也指这个词 “位填充”


当我在 StockOverflow 上查看“填充”的相关标签时”,填充被描述为:

插入内存结构以实现地址对齐的额外空间 - 或 - 框架和 HTML 元素内容之间的额外空间 - 或 - 使用格式化打印命令(如 C 中的 printf* 系列)打印值时的额外空间或零的功能。

背景:

我经常发现与数据类型相关的术语“位填充”,但不明白它是什么,也不知道它对这些有什么作用。

非常感谢您提供任何基于主题的答案。

Nat*_*ica 6

我经常发现与数据类型相关的术语“位填充”,但不明白它是什么,也不明白它对这些有什么作用。

其要点是它们是“浪费”的空间。我说“浪费”是因为虽然填充位使对象更大,但它可以使处理对象更容易(这意味着更快),并且很小的空间浪费可以产生巨大的性能提升。在某些情况下,这是必不可少的,因为 CPU 无法处理这种大小的对象。

假设你有一个类似的结构(所有数字只是一个例子,不同的平台可以有不同的值):

struct foo
{
    short a; // 16 bits
    char  b; // 8 bits 
};
Run Code Online (Sandbox Code Playgroud)

并且您正在使用的机器在一次读取操作中读取 32 位数据。读取单个 foo 不是问题,因为整个对象适合 32 位块。真正成为问题的是当你有一个数组时。关于数组要记住的重要一点是它们是连续的,元素之间没有空间。它只是一个对象,紧随其后的是另一个对象。所以,如果你有一个像

foo array[10]{};
Run Code Online (Sandbox Code Playgroud)

有了这个,第一个foo对象位于 32 位存储桶中。数组的下一个元素将在第一个 32 位桶和第二个 32 位桶中。这意味着该成员a位于两个单独的存储桶中。一些处理器可以做到这一点(有代价),而其他处理器如果你尝试这样做就会崩溃。为了解决这两个问题,编译器将在末尾添加填充位以填充foo它的大小。这意味着 foo 实际上变成了

struct foo
{
    short a; // 16 bits
    char  b; // 8 bits 
    char  _; // 8 bits of padding
};
Run Code Online (Sandbox Code Playgroud)

现在处理器很容易处理 foo自己或数组中的对象。它不需要做任何额外的工作,并且您只为每个对象添加了 8 位。你需要很多对象才能在现代机器上开始重要。

由于未对齐的访问,有时您还需要在类型成员之间进行填充。让我们说你有

struct bar
{
    char c; // 8 bits
    int  d; // 32 bits
};
Run Code Online (Sandbox Code Playgroud)

现在bar是 40 位宽,而且d通常不会再次存储在两个不同的存储桶中。为了解决这个问题,编译器之间增加了填充比特cd

struct bar
{
    char    c; // 8 bits
    char _[3]; // 24 bits
    int     d; // 32 bits
};
Run Code Online (Sandbox Code Playgroud)

现在d保证进入单个 32 位存储桶。


89f*_*a1c 2

bit padding:
Bit padding is the addition of one or more extra bits to a transmission or storage unit to make it conform to a standard size.

As the definition you posted is already correct, I'll try to explain with an example:

假设您必须存储占用少于 32 位的数据,但您有 4 个字节槽。通过访问每个槽来访问该数据更容易,因此您只需完成所有 32 位即可。完成“给定空间”所需但不属于数据一部分的附加位符合位填充。

我确信在多种情况下可能会有更好的例子。任何人都可以随意编辑和/或通过新的改进或示例来完成答案。

希望这可以帮助!