字对齐加载比x64处理器上的未对齐加载更快吗?

dme*_*ter 6 c x86-64 alignment

在x86/64(Intel/AMD 64位)处理器上,在字边界上对齐的变量是否比未对齐的加载操作更快?

我的一位同事辩称,未对齐的载荷很慢,应该避免.他引用了项目填充到结构中的单词边界,作为未对齐加载缓慢的证明.例:

struct A {
  char a;
  uint64_t b;
};
Run Code Online (Sandbox Code Playgroud)

结构A通常大小为16个字节.

另一方面,Snappy压缩器文档指出Snappy假设"未对齐的32位和64位加载和存储很便宜".根据源代码,英特尔32和64位处理器也是如此.

那么:这里的真相是什么?如果和未对齐的载荷减少多少?在哪种情况下?

Dav*_*ven 6

互联网上随机的人我发现,486表示对齐的32位访问需要一个周期.跨越四边形但位于同一缓存线内的未对齐32位访问需要四个周期.跨越多个缓存行的未对齐等可能需要额外的六到十二个周期.

鉴于未对齐的访问需要访问多个内存,几乎按照定义,我对此并不感到惊讶.我认为现代处理器上更好的缓存性能会使成本变得不那么糟糕,但仍然需要避免.

(顺便提一下,如果你的代码对可移植性有任何意义 ...... ia32和后代几乎是唯一支持未对齐访问的现代架构.例如,ARM可以在抛出异常,模拟软件访问之间,或者只是加载错误的值,取决于操作系统!)

更新:这是一个真正去过并测量它的人.在他的硬件上,他估计未对齐的访问速度是对齐的一半.去试试吧...

  • 在最近的 Intel x86(Nehalem 和更新版本)上,未对齐的加载和存储仅在跨越缓存行(或更糟糕的是,页行)时才会受到影响。有关详细信息,请参阅 http://agner.org/optimize/ 的 microarch 指南。值得在循环中添加一个序言,在到达对齐地址之前执行未对齐操作,因此如果您正在处理每个字节,则主循环将在对齐数据上运行。 (2认同)
  • 这是旧的信息,未对齐的装载和商店现在有一个非常小的惩罚:http://lemire.me/blog/2012/05/31/data-alignment-for-speed-myth-or-reality/ (2认同)

Nec*_*lis 5

对齐加载是存储更快,英特尔优化手册中的两段摘录清楚地指出了这一点:

3.6 优化内存访问

对齐数据,注意数据布局和堆栈对齐

...

对齐和转发问题是基于 Intel NetBurst 微架构的处理器出现大延迟的最常见原因之一。

3.6.4 对齐

数据的对齐涉及各种变量:

• 动态分配的变量

• 数据结构的成员

• 全局或局部变量

• 在堆栈上传递的参数

未对齐的数据访问可能会导致严重的性能损失。对于缓存行拆分尤其如此。

在 3.6.4 中的那部分之后,编译器开发人员有一个很好的规则:

汇编/编译器编码规则 45。(H 影响,H 通用性)在自然操作数大小地址边界上对齐数据。如果将通过向量指令加载和存储访问数据,则在 16 字节边界上对齐数据。

其次是对齐规则列表和 3.6.6 中的另一个 gem

用户/源编码规则 6.(H 影响,M 通用性)填充源代码中定义的数据结构,以便每个数据元素与自然操作数大小地址边界对齐。

这两个规则都被标记为影响,这意味着它们可以极大地改变性能,连同摘录,第 3.6 节的其余部分充满了自然对齐数据的其他原因。非常值得任何开发人员花时间阅读这些手册,即使只是为了了解他/她正在处理的硬件。

  • 如果您可以保证未对齐的加载/存储不会跨越缓存线边界,那么现代英特尔就不会受到任何惩罚。(在现代 AMD 上,可能是 32 字节或 16 字节边界)。通常,到目前为止,避免缓存行分割的最简单方法是自然对齐,但如果您有一个 64 字节对齐的结构,那么其中包含未对齐的字段就可以了。 (2认同)

Mar*_*tin 0

未对齐的 32 和 64 位访问并不便宜。

我做了测试来验证这一点。我在 Core i5 M460(64 位)上的结果如下:最快的整数类型是 32 位宽。64 位对齐稍微慢一些,但几乎相同。16 位对齐和 8 位对齐都明显慢于 32 位对齐和 64 位对齐。16 位比 8 位对齐慢。迄今为止最慢的访问形式是非对齐 32 位访问,它比对齐 32 位访问(其中最快)慢 3.5 倍,而未对齐 32 位访问甚至比未对齐 64 位访问慢 40%。

结果:https://github.com/mkschreder/align-test/blob/master/results-i5-64bit.jpg ?raw=true 源代码: https: //github.com/mkschreder/align-test