“双精度”类型是否需要8字节对齐?

问题描述 投票:4回答:5

我了解字对齐,这使得cpu在将整数读入寄存器时只需要读一次。

但是8-byte alignment(让我们假设使用32位系统)是“双精度”吗?有什么好处?如果用于存储“双精度”的空间仅为4字节对齐,将会发生什么情况?

c cpu memory-alignment
5个回答
5
投票

[多个硬件组件可能会因未对齐的装载或存储而受到不利影响。

  • 到内存的接口可能是八个字节宽,并且只能以八个字节的倍数访问内存。装入未对齐的八字节双精度数则需要在总线上进行两次读取。存储更糟,因为对齐的八字节存储区可以简单地将八个字节写入内存,但是未对齐的八字节存储区必须读取两个八字节的存储区,将新数据与旧数据合并,然后写入两个八字节的存储区。
  • 高速缓存行通常为32或64字节。如果将八个字节的对象对齐为八个字节的倍数,则每个对象仅在一个高速缓存行中。如果它们未对齐,则某些对象将部分位于一个高速缓存行中,而部分则位于另一高速缓存行中。然后,加载或存储这些对象需要使用两条高速缓存行而不是一条。这种影响在所有级别的缓存中都会发生(三级在现代处理器中并不罕见)。
  • 内存系统页面通常为512字节或更多。同样,每个对齐的对象仅在一页中,但是一些未对齐的对象在多页中。被访问的每个页面都需要硬件资源:虚拟地址必须转换为物理地址,这可能需要访问转换表,并且必须检测到地址冲突。 (处理器可能同时有多个加载和存储操作在运行。即使您的程序看起来是单线程的,处理器也会提前读取指令并尝试执行可能的指令。因此,处理器可以在执行之前执行加载指令指令已完成,但是,为确保不会引起错误,处理器会检查每个加载指令,以确保它没有从先前存储指令正在更改的地址中加载;如果访问跨越页面边界,则两个部分已加载数据必须单独检查。)

系统对不对齐操作的响应因系统而异。一些系统被设计为仅支持对齐的访问。在这些情况下,未对齐的访问要么导致导致程序终止的异常,要么导致导致执行特殊处理程序的异常,这些处理程序在软件中模拟未对齐的操作(通过执行对齐的操作并根据需要合并数据)。诸如此类的软件处理程序比硬件操作要慢得多。

某些系统支持未对齐的访问,但是与对齐的访问相比,这通常消耗更多的硬件资源。在最佳情况下,硬件执行两项操作,而不是一项。但是某些硬件被设计为像对齐操作一样开始操作,然后在发现操作未对齐时中止操作,并使用硬件中的不同路径重新开始以处理未对齐的操作。在此类系统中,未对齐的访问会严重影响性能,尽管它不如软件处理未对齐的访问的系统严重。

在某些系统中,硬件可能具有多个负载存储执行单元,它们可以执行未对齐访问所需的两个操作,就像一个单元可以执行对齐访问的操作一样快。因此,不对齐访问不会直接导致性能下降。但是,由于多个执行单元由于未对齐的访问而处于忙碌状态,因此它们无法执行其他操作。因此,通常以并行方式执行许多负载存储操作的程序在未对齐访问下的执行速度将比对齐访问下的执行慢。


3
投票

在许多体系结构上,对任何加载/存储单元(短,整数,长)的未对齐访问只是一个例外。编译器负责通过发出较小的访问指令并在无法证明给定指针可用的情况下重新组装在寄存器中来确保不会在可能发生的未对齐数据上发生该错误。

出于性能原因,出于某些原因,在32位系统上双精度的8字节对齐可能很有价值。最明显的是,一个8字节双精度字节的4字节对齐意味着一个元素可以越过两条高速缓存行的边界。内存访问以整个高速缓存行为单位进行,因此未对齐会使访问成本加倍。


0
投票

我刚刚发现the answer:

“ 6。当内存读取可以在32位机器上一次读取4个字节时很有效时,为什么在8个字节的边界上对齐double类型?

重要的是,大多数处理器将具有称为浮点单元(FPU)的数学协处理器。代码中的任何浮点运算都将转换为FPU指令。主处理器与浮点执行无关。所有这些都将在后台完成。

按照标准,双精度类型将占用8个字节。而且,在FPU中执行的每个浮点运算都将具有64位长度。甚至浮点类型也将在执行之前提升为64位。

FPU寄存器的64位长度强制将double类型分配在8个字节的边界上。我假设(没有具体信息)在FPU操作的情况下,数据获取可能有所不同,我的意思是数据总线,因为它通过FPU。因此,双精度类型(预期在8字节边界上)的地址解码将有所不同。这意味着,浮点单元的地址解码电路将没有最后3个引脚。“


0
投票

编辑:

字节对齐的优点是减少了检索数据的存储周期数。例如,如果一个8字节对齐,则可能需要一个周期,现在可能需要2个周期,因为它的一部分是在下一个存储周期中第一次获得的,而第二部分是在下一个存储周期中获得的。

我遇到了这个:“对齐访问的速度更快,因为到内存的外部总线不是单个字节宽的,通常是4或8字节宽(甚至更宽)。因此,CPU不会一次获取单个字节-而是获取4或8字节。从请求的地址开始的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/


0
投票
  • 我似乎记得486的建议是在32位边界上对齐双精度字,因此不需要64位对齐。

© www.soinside.com 2019 - 2024. All rights reserved.