我遇到了这个页面The Lost Art of C Structure Packing,虽然我从来没有必要填写任何结构,但我想学习更多,以便当/如果我需要的话 - 我可以。
它说:
x86或ARM处理器上的基本C数据类型的存储通常不会从内存中的任意字节地址开始。相反,除char之外的每种类型都有对齐要求;字符可以从任何字节地址开始,但是2字节短路必须从偶数地址开始,4字节整数或浮点数必须从可被4整除的地址开始,8字节长或双精度必须从可被8整除的地址开始签名或未签名没有区别。
这是否意味着所有32位处理器(x86,ARM,AVR32,PIC32 ......)都具有此对齐要求?那么16位处理器呢?
如果没有,并且它是特定于设备的,我在哪里可以找到这些信息? 我尝试搜索Microchip XC16 Manual但我找不到对齐要求,说明整数从可被4整除的地址开始。
我认为信息存在,我不是在寻找正确的关键词 - 如果我在网上搜索更多信息,那么“对齐要求”是什么?
答案 0 :(得分:1)
对齐要求有两个注意事项:必填,首选
必需:示例:某些平台需要各种类型,例如int
要对齐。尝试访问未对齐边界上的int
的扭曲代码会导致错误。编译器通常会自动对齐数据以防止出现此问题。
效率:可能允许未对齐访问但导致代码更慢。许多编译器,而不是打包数据,将默认为对齐速度效率的数据。通常,此类编译器允许编译器特定的关键字或编译器选项打包数据,而不是 space 效率。
这些问题适用于不同规模的各种尺寸的各种处理器。 8位处理器可能具有16位数据总线,并且需要对齐16+位类型。适用于64位处理器的兼容C编译器可能仅具有64位类型,甚至char
。可能性很大。
C在max_align_t
中提供整数类型<stddef.h>
。这可以以各种方式用于确定最小的一般对齐要求。
...
max_align_t
这是一种对象类型,其对齐方式与所有上下文中的实现所支持的一致。 ......C11§7.192
C也有_Alignas()
强制对变量进行更严格的对齐。
答案 1 :(得分:1)
这里有两个全球答案。是的,所有处理器都有某种对齐惩罚(ARM,MIPS,x86等)。不,你不能按类型确定。所有ARM都没有相同的对齐惩罚,尽管人们认为他们知道旧的ARMv4和ARMv5,你可以以可预测的方式进行未对齐的访问,这种可预测的方式不是我们大多数人所希望的,而你必须启用它。 MIPS和ARM以及其他人可能会对未对齐的传输进行严厉处罚,您将遇到数据错误。但是由于程序员编程等的性质,至少ARM的默认设置是在某些/更新的内核上禁用。您可以根据需要禁用它或启用它。
所有处理器都会因未对齐传输而受到损失,性能下降,并且这些命中发生在各个层,有时在核心,核心边缘,每个缓存层以及ram的外层。由于设计变化如此广泛,您无法提出单一规则。
同样,由于编译器中的对齐是实现定义的,因此您无法编写可移植代码。因此,如果您正在处理处理器(可能是ARM,因为那是大多数人被咬过的地方)启用了未对齐的错误,最便携的解决方案,但不是万无一失的,是用64位变量启动结构,然后是32那么16然后是8.编译器倾向于按照你定义它们的顺序放置东西,只要整个结构在该目标的右边界上开始,那么变量将正确地对齐,不需要填充。除了不使用结构,或禁用对齐检查并遭受前端性能命中之外,没有全局解决方案。
请注意,我们今天通常处理的32位臂使用64位AMBA / AXI总线而不是32位,如果启用,它们仍然可以检查所有对齐(16,32,64)以进行传输,但未对齐的性能达到至少在AMBA / AXI级别,除非你越过64位对齐的边界,否则不要打你。你可能仍然有一个额外的缓存行命中,但如果你没有AMBA / AXI命中率,这是不可能的。