【问题标题】:Unaligned memory access未对齐的内存访问
【发布时间】:2013-10-21 13:06:31
【问题描述】:

我正在玩 C 中的内存地址,并且想知道这个名为 未对齐的内存访问的主题。

我目前使用的是带有 Linux 内核的 x86 Intel,但本着架构和操作系统不可知论的精神提出这个话题 - 尽管以下是 相当 Linux 和硬件特定的:


当我从一个未对齐的地址读取/写入一个简单类型时,我不会出错。日志中没有消息或任何内容。我也试过:

perf top -e alignment-faults
# And with PID
perf top -p NNN -e alignment-faults

但没有命中。

打开alignment checking by:

__asm__("pushf\norl $0x40000,(%esp)\npopf");

给出“想要的”结果:

Bus error (core dumped)

(但perf 中仍然没有消息。)


我的问题是硬件 + 操作系统是如何处理的,什么是最佳的。我的想法和问题到处都是,但我会尝试表达一些具体的观点:

  1. CPU是否默认有对齐检查on,但是内核检测到off支持并指示它不检查
  2. 作为内核,至少我在其他硬件上遇到过这种情况,由于某些驱动程序试图访问未对齐的内存,可能会出现 oops:内核是否在 alignment check 模式下运行?还是可能只是代码的某些部分起作用?
  3. 由于访问未对齐的内存需要更多资源;在软件的测试阶段启用对齐检查是否是个好主意,例如上面的装配线?这是否也会使其更便携?

我还有很多关于这个的问题,但现在就这样吧。

【问题讨论】:

  • 对齐成为一个话题的一个重要原因是,有些架构会检查,而有些架构不会。那些可能有也可能没有启用/禁用。此外,检查是在硬件中完成的,因此内存/获取周期有故障。
  • 从内存中工作……英特尔 (CISC) 芯片可以管理未对齐的写入——我相信会以速度为代价。一般的 RISC 芯片(特别是 SPARC,我也相信其他芯片)在请求访问未对齐的数据时会产生总线错误(奇数内存地址上的 2 字节数量;地址上的 4 字节数量不是4 字节)等。一些芯片(DEC Alpha)会生成内核陷阱并处理内核中的未对齐访问——这非常慢。有一个命令,uam,用于控制程序是在未对齐的内存访问中崩溃还是发生内核陷阱。
  • 对于您的第一个问题,我认为没有开/关模式,更像是操作系统或编译器是否可以在软件中处理未对齐的内存访问引发的问题。如果它可以处理,那么我看不出为什么它会为某些代码关闭而不为其他代码启用。希望您发现以下两个链接有用,msdn.microsoft.com/en-us/library/aa290049%28v=vs.71%29.aspxlwn.net/Articles/260832
  • 谢谢各位。这正在慢慢下沉,我会说通过答案和 cmets 累积的信息很好,所以我会接受(并在手册等中继续阅读;))。
  • @AquaAsh:我的想法是,在内核中,如果它可以提高 CPU 的性能,可以将其关闭。我最初的想法是,如果它支持它,(对齐修复),将首先发出一个请求(由 CPU)。如果 MMU 不回复 - 尝试修复。 – 但是,通过如何在硬件级别上实现这一点,即使在有效请求上也可能会造成性能损失。第二点是,(对于交叉支持),为生产关键的代码实现这一点。相信我已经读过一些 CPU 可能会以错误的对齐方式回复,但随后数据会受到损害。 (因此“让硬件处理它”)

标签: c memory assembly kernel


【解决方案1】:

试着给出部分答案。

CPU 是否默认开启对齐检查,但内核 检测到支持 off 并指示它不检查?

这取决于拱门,甚至在同一个拱门上,未对齐内存上的某些指令可能可以由硬件处理,而其他指令则不能。

作为内核,至少我在其他HW上经历过这个,可以搞定 哎呀,由于某些驱动程序试图访问未对齐的内存: 内核在对齐检查模式下运行?或者它也许只是确定的 部分代码是做什么的?

硬件不支持的未对齐内存访问会导致陷阱,并且内核具有陷阱/异常的处理程序。 我一直在研究 ppc,此类异常将根据指令(从 PC 获取)进行处理;一些指令得到处理,程序将恢复;其他一些可能会导致程序终止,因为内核无法处理它。一个这样的例子是用于实现比较和交换逻辑的 stwcx 指令。

由于访问未对齐的内存需要更多资源;是不是很好 启用对齐检查的想法,例如上面的程序集 线,在软件的测试阶段?这也会使它更多 便携吗?

实际上,如果您在大型项目中有大量遗留代码,这可能不是一个好主意.....但它应该适合新代码。

【讨论】:

    猜你喜欢
    • 2010-11-07
    • 1970-01-01
    • 2014-06-25
    • 2013-05-09
    • 1970-01-01
    • 2011-07-04
    • 2012-08-03
    • 2011-07-31
    相关资源
    最近更新 更多