当前位置: 首页 > 知识库问答 >
问题:

在x86上成功的未对齐访问的实际效果是什么?

宗政安歌
2023-03-14

我总是听说未对齐的访问是不好的,因为它们要么会导致运行时错误并使程序崩溃,要么会减慢内存访问速度。但是我找不到任何关于它们会减慢多少速度的实际数据。

假设我在x86上并且有一些(但未知的)未对齐访问份额——实际上可能的最糟糕的减速是什么,以及如何在不消除所有未对齐访问并比较两个版本代码的运行时间的情况下估计它?

共有3个答案

贺波
2023-03-14

一般来说,在现代处理器上估计速度是极其复杂的。这不仅适用于未对齐的访问,而且在一般情况下也是如此。

现代处理器具有流水线架构、乱序和可能并行执行指令以及许多其他可能影响执行的东西。

如果不支持未对齐的访问,则会出现异常。但如果它得到支持,你可能会或可能不会减速,这取决于许多因素。这些因素包括在未对齐的指令之前和之后执行的其他指令(因为处理器可能能够在执行之前的指令时开始提取数据,或者在等待时继续执行后续指令)。

如果未对齐的访问发生在cacheline边界上,则会发生另一个非常重要的区别。一般来说,对于未对齐的访问,可能会发生对缓存的2倍访问,真正的减速是如果访问跨越cacheline边界并导致双缓存未命中。在最坏的情况下,2字节的未对齐读取可能需要处理器将两个cacheline刷新到内存中,然后从内存中读取2个chacheline。这是大量数据的移动。

优化的一般规则也适用于此:首先编码,然后度量,然后当且仅当存在问题时,找出解决方案。

戚翰飞
2023-03-14

在一些Intel微架构上,由cacheline边界分割的负载比平时需要十几个周期,而由页面边界分割的负载需要超过200个周期。如果负载在循环中持续不对齐,那么值得进行两个对齐的负载并手动合并结果,这已经够糟糕的了,即使p0026 r不是一个选项。即使SSE的未对齐负载也救不了你,除非它们正好从中间拆分。

在AMD上,这从来都不是问题,Nehalem的问题基本上消失了,但仍然有很多Core2的存在。

黄伟
2023-03-14

它取决于指令,对于大多数x86 SSE加载/存储指令(不包括未对齐的变体),它将导致故障,这意味着它可能会使程序崩溃或导致大量异常处理程序的往返(这意味着几乎或所有性能都会丢失)。由于未对齐的加载/存储变体执行部分读/写操作,因此它们的运行周期是IIRC的两倍,因此需要2才能执行该操作(除非您很幸运,并且它在缓存中,这大大减少了惩罚)。

对于一般的x86加载/存储指令,代价是速度,因为读或写需要更多的周期。未对齐也可能会影响缓存,导致缓存线分裂和缓存边界跨越。它还可以防止读写的原子性(对于x86的所有对齐读/写都有保证,屏障和传播是另一回事,但对未对齐的数据使用锁定指令可能会导致异常或大大增加bu锁所带来的本已巨大的惩罚),这对于并发编程来说是不允许的。

Intels x86

Agner Fog的优化手册应该有您在原始循环吞吐量方面寻找的确切数字。

 类似资料:
  • 也许我误解了什么,但x86中的未对齐访问似乎带来了安全问题,例如返回地址完整性问题。 > 为什么x86设计器首先允许未对齐的访问?(性能是我能想到的唯一好处。) 如果x86设计人员允许这种未对齐的访问问题,他们应该知道如何解决它,不是吗?是否可以使用静态技术或清理技术检测未对齐的访问?

  • 我想模拟x86/x86_64上禁止未对齐内存访问的系统。是否有一些调试工具或特殊模式来执行此操作? 当使用为SPARC或其他类似CPU设计的软件(C/C)时,我想在几台x86/x86_64PC上运行许多(CPU密集型)测试。但是我对Sparc的访问是有限的。 正如我所知,Sparc总是检查内存读写的对齐是否正常(从任何地址读取一个字节,但仅当地址可被4整除时才允许读取一个4字节的字)。 可能是Va

  • 问题内容: 我想用x86 / x86_64上禁止的未对齐内存访问来模拟系统。有一些调试工具或特殊模式可以做到这一点吗? 当使用为SPARC或其他类似CPU设计的软件(C / C ++)时,我想在几台x86 / x86_64 PC上运行许多(CPU密集型)测试。但是我对Sparc的访问受到限制。 据我所知,Sparc总是检查内存读写的对齐是否自然(从任何地址读取一个字节,但仅当地址被4整除时才读取4

  • 我知道C中的未对齐访问是什么,它可能会导致某些处理器UB。 我想知道这样写在NASM汇编上的代码中是否存在同样的问题:

  • 在回答中,我说过长期以来(在x86/x86_64上)未对齐的访问速度几乎与对齐的访问速度相同。我没有任何数字来支持这个说法,所以我为它创建了一个基准。 你看到这个基准有什么缺陷吗?你能改进它吗(我的意思是,增加GB/秒,以便更好地反映真相)?

  • 问题内容: 我正在开发一个宠物的开源项目,该项目实现了一些流密码算法,并且只有在ARM处理器上运行该bug时,我才遇到问题。我什至尝试在qemu下的x86中运行ARM二进制文件,但该错误并未在那里触发。 该错误的具体机制仍然难以捉摸,但是我最好的选择是相信它是由程序中未对齐的内存访问尝试引起的,这是qemu实现的,但被开发板中的真正ARM处理器默默忽略了。 因此,由于该问题很难诊断,所以我想知道是