我在哪里可以找到任何编译器的对齐要求?
我遇到了这个页面,C结构包装的失落艺术,虽然我从来没有实际填充任何结构,但我想多了解一些,以便在/如果我也需要 - 我可以。
它说:
x86或ARM处理器上基本C数据类型的存储通常不在内存中的任意字节地址处开始。 相反,除char以外的每种类型都有对齐要求; 字符可以从任何字节地址开始,但2字节短路必须从偶数地址开始,4字节整数或浮点数必须以可被4整除的地址开始,并且8字节长或双字必须在可被8整除的地址处开始签名或不签名没有区别。
这是否意味着所有32位处理器(x86,ARM,AVR32,PIC32,...)都具有这种对齐要求? 那么16位处理器呢?
如果没有,并且它是设备特定的,我在哪里可以找到这些信息? 我试图通过Microchip XC16手册进行搜索,但是我找不到对齐要求,说明整数始于可以被4整除的地址。
我假设这些信息在那里,而且我不在寻找正确的关键词 - 如果我要在网上搜索以获取更多信息,那么称为“对齐要求”是什么?
对齐要求有两个注意事项:必需的,首选的
必需:示例:某些平台需要各种类型,例如要对齐的int
。 尝试在未对齐边界上访问int
扭曲代码导致错误。 编译器通常会自动对齐数据以防止此问题。
效率:可能允许未对齐的访问,但会导致代码变慢。 许多编译器,而不是打包数据,将默认对齐数据以提高速度效率。 通常,这种编译器允许使用编译器特定的关键字或编译器选项来打包数据,以提高空间利用率。
这些问题在不同程度上适用于各种规模的各种处理器。 一个8位处理器可能有一个16位数据总线,并且要求对齐16位以上的类型。 用于64位处理器的兼容C编译器可能只有64位类型,甚至是char
。 可能性很大。
C在<stddef.h>
提供了一个整数类型max_align_t
。 这可以以各种方式用于确定最小一般对齐要求。
... max_align_t
这是一种对象类型,其对齐方式与实现在所有上下文中支持的一样大; ... C11§7.192
C还有_Alignas()
来_Alignas()
变量的更严格的对齐。
这里有两个全局答案。 是的,所有的处理器都有某种类型的对齐惩罚(ARM,MIPS,x86等)。 不,你不能通过类型来确定。 尽管人们认为他们知道较早的ARMv4和ARMv5,但所有的ARM都没有相同的对齐惩罚,您可以以可预测的方式进行未对齐的访问,这种可预测的方式并非我们大多数人所偏好的,您必须启用它。 MIPS和ARM以及其他可能会对未对齐的传输造成严重的惩罚,您将会遇到数据错误。 但由于程序员编程的性质等原因,至少对于ARM来说,默认情况下会禁用某些/更新的内核。 您可以禁用它或启用它,无论您想要的方式。
所有处理器都会对未对齐的传输进行惩罚,性能会受到损失,而这些命中发生在各个层,有时位于核心,核心边缘,每个缓存层以及ram外层。 由于设计差异很大,你不能拿出一条规则。
同样,因为编译器中的对齐是实现定义的,所以你不能编写可移植的代码。 因此,如果你正在处理一个处理器(可能是一个ARM,因为这是大多数人被咬的地方),但是最便携的解决方案,但并非万无一失,是用64位变量来启动你的结构,然后是32然后是16,然后是8.编译器倾向于按照您定义的顺序放置事物,只要整个结构从该目标的右边界开始,那么变量就会正确对齐,不需要填充。 除了不使用结构,或者禁用对齐检查并遭受前端性能命中之外,没有全局的解决方案。
请注意,我们今天通常处理的32位分支使用的是64位AMBA / AXI总线,而不是32位,如果启用,它们仍然可以检查所有的传输对齐(16,32,64),但未对齐的性能至少在AMBA / AXI级别不会打你,除非你穿过64位对齐的边界。 你可能仍然有一个额外的缓存行命中,但如果你没有AMBA / AXI命中,这是不太可能的。
链接地址: http://www.djcxy.com/p/54091.html上一篇: Where can I find what the alignment requirement for any arbitrary compiler?