有这么多不同的处理器模型,我将仅以理论和一般术语来回答这个问题。
考虑一个 16 字节对象的数组,该数组的起始地址是 8 字节的倍数,但不是 16 字节的倍数。假设处理器有一个八字节总线,如问题中所示,即使某些处理器没有。但是,请注意,在数组中的某个点,其中一个对象必须跨越页边界:内存映射通常在以 4096 字节边界开始的 4096 字节页中工作。对于八字节对齐的数组,数组的某些元素将从一页的字节 4088 开始,一直到下一页的字节 7。
当程序试图加载跨越页面边界的 16 字节对象时,它不能再进行单个虚拟到物理内存映射。它必须对前八个字节进行一次查找,对后八个字节进行另一次查找。如果加载/存储单元不是为此设计的,则指令需要特殊处理。处理器可能会中止执行指令的初始尝试,将其分成两个特殊的微指令,然后将它们发送回指令队列以执行。这会使指令延迟许多处理器周期。
此外,正如 Hans Passant 所指出的,对齐与缓存相互作用。每个处理器都有一个内存缓存,缓存通常被组织成 32 字节或 64 字节的“行”。如果加载一个 16 字节对齐的 16 字节对象,并且该对象在缓存中,那么缓存可以提供一个包含所需数据的缓存行。如果您从非 16 字节对齐的数组中加载 16 字节对象,则数组中的某些对象将跨越两个缓存行。加载这些对象时,必须从缓存中提取两行。这可能需要更长的时间。即使获得两条线不需要更长的时间,也许是因为处理器设计为每个周期提供两条高速缓存线,这可能会干扰程序正在执行的其他操作。通常,一个程序会从多个地方加载数据。如果负载是有效的,处理器可能能够同时执行两个。但是,如果其中一个需要两条缓存线而不是正常的一条,那么它会阻止同时执行其他加载操作。
此外,一些指令明确要求对齐地址。处理器可能会更直接地发送这些指令,绕过一些修复没有对齐地址的操作的测试。当这些指令的地址被解析并发现未对齐时,处理器必须中止它们,因为修复操作已被绕过。