首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >沿4字节边界对齐

沿4字节边界对齐
EN

Stack Overflow用户
提问于 2009-08-06 09:51:44
回答 9查看 23.9K关注 0票数 12

我最近开始考虑对齐..。这是我们通常不需要考虑的事情,但我已经意识到一些处理器要求对象沿4字节边界对齐。这到底是什么意思,以及哪些特定系统有对齐要求?

假设我有一个任意的指针:

unsigned char* ptr

现在,我尝试从内存位置检索一个双精度值:

double d = **((double*)ptr);

这会造成问题吗?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2009-08-06 10:05:27

这肯定会在某些系统上造成问题。

例如,在基于ARM的系统上,您无法寻址未与4字节边界对齐的32位字。这样做将导致访问冲突异常。在x86上,您可以访问这种未对齐的数据,尽管性能会受到一些影响,因为必须从内存中获取两个单词,而不是一个单词。

票数 22
EN

Stack Overflow用户

发布于 2009-08-06 10:33:26

以下是对对齐的描述:

4.1.1对齐单词、双字、四字和双四字

单词、双字和四字不需要在自然边界上的内存中对齐。字、双字和四字的自然边界分别是偶数地址、可被4整除的地址和可被8整除的地址。然而,为了提高程序的性能,数据结构(尤其是堆栈)应该尽可能在自然边界上对齐。这是因为处理器需要两次存储器访问才能进行非对齐的存储器访问;对齐的访问只需要一次存储器访问。跨越4字节边界的字或双字操作数或跨越8字节边界的四字操作数被视为未对齐,并且需要两个单独的内存总线周期进行访问。

一些在双四字上操作的指令要求内存操作数在自然边界上对齐。如果指定了未对齐的操作数,则这些指令会生成通用保护异常(#GP)。双四字的自然边界是可被16整除的任何地址。在双四字上操作的其他指令允许不对齐访问(不会生成一般保护异常)。然而,从存储器访问未对齐的数据需要额外的存储器总线周期。

请不要忘记,参考手册是负责任的开发人员和工程师的最终信息来源,因此,如果您处理的是英特尔CPU等有详细记录的内容,请查看参考手册中有关该问题的说明。

票数 14
EN

Stack Overflow用户

发布于 2009-08-06 11:51:02

是的,这可能会导致许多问题。C++标准实际上并不能保证它能正常工作。你不能随意地在指针类型之间进行转换。

当您将字符指针转换为双指针时,它将使用reinterpret_cast,这将应用实现定义的映射。您不能保证结果指针将包含相同的位模式,或者它将指向相同的地址或任何其他地址。在更实际的术语中,也不能保证您正在读取的值是正确对齐的。如果数据是以一系列字符的形式写入的,那么它们将使用字符的对齐要求。

至于对齐意味着什么,本质上就是值的起始地址应该可以被对齐大小整除。例如,地址16在1、2、4、8和16字节边界上对齐,因此在典型的CPU上,这些大小的值可以存储在那里。

地址6没有在4字节边界上对齐,所以我们不应该在那里存储4字节的值。

值得注意的是,即使在不强制或要求对齐的CPU上,访问未对齐值通常仍会显著减慢。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1237963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档