但是对于“double”来说,8字节对齐(假设为32位系统)是否必要?这有什么好处?如果用于存储“double”的空间只有4字节对齐会发生什么?
多个硬件组件可能会受到未对齐的负载或存储的影响。
系统对未对齐操作的响应因系统而异。某些系统仅支持对齐访问。在这种情况下,未对齐访问会导致异常,导致程序终止或引发执行特殊处理程序的异常,该处理程序通过执行对齐操作并根据需要合并数据来模拟未对齐操作。此类软件处理程序比硬件操作慢得多。
一些系统支持非对齐访问,但通常会消耗比对齐访问更多的硬件资源。在最好的情况下,硬件会执行两个操作而不是一个操作。但是,有些硬件被设计成在开始操作时像对齐操作一样,然后在发现操作不对齐时中止它,并使用硬件中的不同路径重新开始处理非对齐操作。在这种系统中,非对齐访问具有显着的性能惩罚,尽管它不像软件处理非对齐访问的系统那样大。我记得对于486处理器的建议是将双精度数据对齐到32位边界,因此要求64位对齐不是强制性的。
你似乎认为数据总线宽度和处理器位数之间有关系。虽然通常情况下是这样,但两者都可以存在变化。例如,奔腾处理器是32位处理器,但其数据总线大小为64位。
缓存提供了其他东西,这可能解释了为什么对于64位类型具有64位对齐的有用性。在这里,外部总线不是因素,重要的是缓存行大小。跨越缓存行的数据访问成本比未跨越它的数据访问成本更高(即使在两种情况下都不对齐)。按照类型的大小进行对齐确保它们不会跨越缓存行,只要缓存行大小是类型大小的倍数。
编辑:
字节对齐的优点在于减少检索数据所需的内存周期数。例如,如果8个字节对齐,则可能只需要一个周期,而现在可能需要2个周期,因为第一次获取了其中的一部分,下一个内存周期中获取其余部分。
我发现这个: “对齐访问更快,因为到内存的外部总线不是单字节宽-通常是4或8字节宽(甚至更宽)。因此,CPU不会一次获取单个字节-它获取从请求地址开始的4或8个字节。因此,内存地址的2或3个最低有效位实际上并未由CPU发送-外部内存只能在总线宽度的倍数地址处读取或写入。如果您请求地址“9”处的字节,则CPU实际上会要求内存提供从地址8开始的字节块,并将第二个字节加载到您的寄存器中(丢弃其他字节)。
这意味着未对齐的访问可能需要从内存中读取两次:如果您请求从地址9开始的8个字节,CPU 必须获取从地址8开始的8个字节以及从地址16开始的8个字节,然后屏蔽您想要的字节。另一方面,如果您请求从地址8开始的8个字节,则只需要进行一次获取。有些 CPU 甚至不会执行此类未对齐的加载 - 它们将仅引发异常(甚至默默地加载错误的数据!)。 您可以查看此链接以获取更多详细信息。http://www.ibm.com/developerworks/library/pa-dalign/我刚刚找到了答案:
"6. 当在32位机器上进行内存读取时,以4字节为单位的读取效率很高,那么为什么双精度类型应该对齐在8字节边界上呢?
需要注意的是,大多数处理器都有数学协处理器,称为浮点运算单元(FPU)。代码中的任何浮点操作都将被转换为FPU指令。主处理器与浮点执行无关。所有这些都将在幕后完成。
根据标准,双精度类型将占用8个字节。而且,在FPU中执行的每个浮点操作都将具有64位长度。甚至在执行之前,浮点类型也会被提升为64位。
FPU寄存器的64位长度强制双精度类型分配在8字节边界上。我假设(我没有确切的信息)在FPU操作的情况下,数据获取可能会有所不同,我的意思是数据总线,因为它进入FPU。因此,双精度类型的地址解码将不同(预期在8字节边界上)。这意味着,浮点单位的地址解码电路将没有最后3个引脚。"