数据对齐

来源:互联网 发布:软件安全性测试报告 编辑:程序博客网 时间:2024/06/08 07:09

     为了速度和正确性去对齐你的数据

    对于直接使用内存的所有程序员来说,数据对齐是一个重要问题。即使软件运行, 数据对齐也会影响软件的性能。 如本文所示,理解对齐的本质也可以解释一些处理器的“怪异”行为。

内存访问的最小单位

程序员习惯把内存看成是一个简单的字节数组。在C语言及其派生的语言中,char *一般认为是一块内存,甚至在Java语言中也有byte []类型来表示原始内存。

Figure 1. How programmers see memory
How Programmers See Memory


但是,计算机的处理器不会以字节大小的块来读取和写入存储器。 相反,它以两个、四个、八个、十六个甚至三十二个字节的块访问存储器。 这些尺寸是我们将调用处理器访问内存的最小尺寸。

Figure 2. How processors see memory
How Some Processors See Memory

高级程序员如何看待内存和现代处理器如何使用内存之间的区别是本文需要探索的有趣问题。


如果您不了解并解决软件中的对齐问题,则以下情形(按严重性的升序)都是可能的:

  • 您的软件将运行较慢。
  • 您的应用程序将锁定。
  • 您的操作系统将崩溃。
  • 您的软件将silently fail,产生不正确的结果。

对齐的基本原理

为了说明对齐背后的原理,检查一个常数任务,以及它如何受处理器的访问最小内存单元的影响。 任务很简单:首先从地址0读取四个字节到处理器的寄存器。 然后从地址1读取四个字节到同一个寄存器。

首先检查在一个单字节最小内存访问的处理器上会发生什么:

Figure 3. Single-byte memory access granularity
Single-byte memory access granularity

这和程序员看待内存工作模式是一样的:从地址0读取常数的操作和地址1读取的操作是一样的。现在看看在双字节最小内存访问单元的处理上会发生什么,如原始的68000 :

Figure 4. Double-byte memory access granularity
Double-byte memory access granularity

当从地址0读取时,具有两字节最小内存访问的处理器占用具有一字节最小内存访问的处理器访问数量的一半。 因为每个内存访问都需要固定的开销,最大限度地减少访问次数真的可以提高性能。

然而,注意从地址1读取时会发生什么。因为地址不会均匀地落在处理器的存储器访问边界上,所以处理器有额外的工作要做。 这样的地址称为未对齐地址。 因为地址1未对齐,所以具有两字节粒度的处理器必须执行额外的存储器访问,从而减慢操作。

最后,检查在具有四字节内存访问粒度的处理器上会发生什么,如68030或PowerPC®601:

Figure 5. Quad-byte memory access granularity
Quad-byte memory access granularity

具有四字节粒度的处理器可以从对齐地址中一次读取四个字节。 还要注意,从未对齐地址读取将使访问计数翻倍。

现在,了解了对齐数据访问背后的基础知识,可以探索一些与对齐相关的问题。


惰性处理器

处理器在被指示访问未对齐地址时必须执行一些操作。 回到在具有四字节粒度的处理器上从地址1读取四个字节的示例,您可以准确地了解需要做什么:

Figure 6. How processors handle unaligned memory access

How processors handle unaligned memory access

处理器需要读取未对齐地址的第一个块,并从第一个块中移出“不需要的”字节。然后,它需要读取未对齐地址的第二个块,并移出其一些信息。最后,将两者合并在一起以放置在寄存器中。这是很多工作。 

有些处理器并不愿意为你做所有的工作。 

原来的68000是一个具有两个字节粒度的处理器,并且没有拷贝未对齐地址的数据。当呈现这样的地址时,处理器将抛出异常。原来的Mac OS没有非常友好地对这个异常,并且通常会要求用户重新启动机器。

后来的处理器在680x0系列,如68020,解除了这个限制,并为您执行必要的工作。这解释了为什么一些旧的软件工作在68020崩溃在68000.它也解释了为什么,回来的时候,一些旧Mac编码器初始化指针与奇地址。在原始的Mac上,如果指针被访问而没有重新分配到有效的地址,Mac将立即下降到调试器。通常他们可以检查调用链栈,并找出错误在哪里。

 所有处理器都有有限数量的晶体管来完成工作。添加非对齐地址访问支持削减到这个“晶体管预算”。这些晶体管可以另外用于使处理器的其他部分更快地工作,或者完全添加新的功能。

 以速度名称牺牲未对齐地址访问支持的处理器的示例是MIPS。 MIPS是一个处理器的一个很好的例子,它以快速完成实际工作的名义去除了几乎所有的轻易。 

PowerPC采用混合方法。到目前为止,每个PowerPC处理器都有硬件支持未对齐的32位整数访问。虽然您仍然为未对齐访问付出性能损失,但它往往很小。

 另一方面,现代PowerPC处理器缺乏硬件支持未对齐的64位浮点访问。当被要求从内存加载未对齐的浮点数时,现代PowerPC处理器将抛出异常,并让操作系统在软件中执行对齐操作。在软件中执行对齐比在硬件中执行慢得多。



原文网址:http://www.ibm.com/developerworks/library/pa-dalign/

0 0