【问题标题】:how is padding beneficial?填充有什么好处?
【发布时间】:2014-02-06 23:01:37
【问题描述】:
struct MixedData
{
    char Data1;
    short Data2;
    short Data3;
    double Data4;
    int Data5;
    double Data6;
};

上面的struct 将被自动“填充”。但我不明白“填充”有什么好处。

【问题讨论】:

    标签: c structure padding


    【解决方案1】:

    因为大多数平台在读取未对齐的数据时都会遭受性能损失。例如,一个 64 位宽的内存控制器可以在一个“周期”内读取一个 double,只要它正确对齐,如果没有对齐,则需要 2 个周期来读取它并不必要地加载 MC。有些平台甚至无法读取未对齐的数据。这就是为什么必须使用填充来确保所有内容都以最佳方式对齐。

    【讨论】:

    • 但我想知道为什么大多数平台在读取未对齐的数据时会遭受性能损失。同样正如您所写的 a 64 bit wide memory controller can read a double in one "cycle" as long as it is aligned properly, if not, it will take 2 cycles to read it and load the MC unnecessarily ,为什么会发生这种情况?
    • @kevingomes - 因为 MC 本身可以访问其宽度的多个内存地址。例如,64 位 MC 可以从地址 0、64、128 等读取。如果您的 64 位数据在 64 位边界上对齐,MC 将一口气读取所有 64 位,如果未对齐,内存控制器将读取一个 64 位块,从中提取数据,读取下一个块以提取其余数据,并可能执行移位和屏蔽操作以将两个块组合成一个 64 位数据类型。
    • 64 bit boundary 是什么意思?
    • 如果是 8 字节的倍数,则表示地址,例如64 位。我使用字节的原因是因为字节是最小的可寻址单元,如果你想要一个位,你必须寻址那个字节并从那里提取位。
    • @kevingomes - short 只有 2 个字节,所以它是 2 的倍数对齐。请检查 double 对齐方式。
    【解决方案2】:

    在某些 CPU 架构上,尝试从未对齐的内存地址加载一个字可能需要很多 CPU 周期,而从对齐的地址加载一个字将需要几个 CPU 周期。一些 CPU 架构甚至无法从未对齐的地址加载。

    编译器很有帮助,可以尝试将结构成员变量放置在 CPU 的最佳位置。

    【讨论】:

    • cycle 指的是什么?
    • @kevingomes - 如果您的 CPU 以 2 GHz 运行,这意味着它以每秒 20 亿个周期运行,那就是一个周期。
    • 为什么未对齐的内存需要更多的周期?
    【解决方案3】:

    某些计算机(例如 RISC,有时基于 ARM)只能在特定的内存边界访问,例如,double。其他计算机(例如基于 8086 的系列)可以进行任意访问,但会降低性能。

    【讨论】:

      【解决方案4】:

      只是为了扩展已经通过视觉表示给出的答案。

      当一个单词在内存中对齐时,它看起来像这样,并且只需要一次阅读。

      +-------------------------+-------------------------+
      | XX XX XX XX XX XX XX XX | 12 34 56 78 90 ab cd ef |
      +-------------------------+-------------------------+
                                 ^-----------------------^
                                           Cycle 1
      

      当它未对齐时,某些架构需要两个周期来获取字,因为它一次无法读取边界,或者内存地址在内部表示为字大小的倍数。他们需要获取两倍的数据量,丢弃无用的部分并将有用的部分组合起来。

      +-------------------------+-------------------------+
      | XX XX XX XX XX 12 34 56 | 78 90 ab cd ef XX XX XX |
      +-------------------------+-------------------------+
                      ^--------^ ^--------------^
                        Cycle 1      Cycle 2
      

      【讨论】:

      • 在许多情况下,情况比您描述的更糟糕,原因有两个: (1) 某些处理器没有细分内存访问的能力。尝试从不是四的倍数的地址读取 32 位值只会崩溃。 (2) 硬件通常只能访问大小为 2 次方的块中的数据。对于将 int64 存储到地址 3 的处理器来说,需要向地址 3 写入一个字节,向地址 4 写入四个字节,向地址 8 写入两个字节,向地址 8 写入一个字节,以及向地址 12 写入一个字节。因此,未对齐访问的代价不是一个周期,而是三个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-04
      • 1970-01-01
      • 2010-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多