函数指针的对齐要求

时间:2014-11-28 07:09:26

标签: c++ alignment function-pointers

我们知道应该正确对齐数据指针的值。例如,指向double的指针的值应该是8的倍数。所以我想知道指向函数的指针是否有类似的要求。

1 个答案:

答案 0 :(得分:5)

数据和代码的对齐高度依赖于机器。

在许多处理器上,例如在未对齐的地址读取double将导致错误(硬件异常,陷阱或任何您想要调用的地方) - 这要么用软件处理[慢,通常为10-1000x比对齐访问慢]或导致执行操作的应用程序失败(类似于访问现代操作系统中的无效内存位置)。在例如x86上,它会更慢,但通常不会失败,因为处理器至少在某些情况下必须执行两个较小的读取操作,并在获得double的值之前将它们组合起来。 / p>

代码也可能有对齐。大多数RISC处理器都有固定大小的代码字 - 4个字节是一个通用大小,它们应该与该大小对齐。处于“拇指”模式的ARM使用2字节指令大小,其中一些指令在另一个字之后具有额外数​​据。

另一方面,x86具有“单字节”对齐要求,例如68K将要求代码仅以2字节对齐。因此,在这方面,对齐需求会有所不同。除此之外,有效率的原因需要一定的对齐 - 例如,在8,16或32字节边界处启动函数/分支通常是有益的,并且我知道一些旧的x86处理器具有“多少分支预测的限制”给定N个字节的代码可能有“ - 意味着如果你在一小段代码中有许多不同的分支,有些则必须没有分支预测,因为该位置的”插槽“已经满了。

因此,出于性能原因,编译器(有时)会填充代码以对齐函数。然而,这并不总是一个胜利 - 它用“填充”浪费缓存空间,它实际上取决于代码的使用方式。编译器通常知道这一点,至少如果您使用基于反馈/配置文件的优化(其中代码使用检测来运行以计算代码的使用方式,并且优化基于此结果)。

但是,通常,函数指针可以指向“代码”的合法地址,因此基本要求通常是1,2或4个字节,基于处理器本身的体系结构。