我目前正在尝试构建一个可以在多种机器上运行的代码,从手持口袋和传感器到数据中心的大型服务器。
这些架构之间的(许多)差异之一是对齐内存访问的要求。
“标准”x86 CPU 不需要对齐内存访问,但许多其他 CPU 需要它,如果不遵守规则,就会产生异常。
到目前为止,我一直在通过使用 Packed 属性(或 pragma)强制编译器对已知有风险的特定数据访问保持谨慎来处理它。而且效果很好。
问题是,编译器非常谨慎,以至于在此过程中损失了大量性能。
由于性能很重要,因此我们最好重写部分代码以专门在严格对齐的 cpu 上工作。另一方面,这样的代码在支持未对齐内存访问的 cpu(例如 x86)上会变慢,因此我们想使用它only在需要严格对齐内存访问的CPU上。
现在的问题是:
如何在编译时检测目标体系结构需要严格对齐的内存访问? (或者反过来)
据我所知,没有任何 C 实现提供任何预处理器宏来帮助您解决这个问题。由于您的代码应该可以在各种机器上运行,因此我假设您可以访问各种机器进行测试,因此您可以通过测试程序找出答案。然后你可以编写自己的宏,如下所示:
#if defined(__sparc__)
/* Unaligned access will crash your app on a SPARC */
#define ALIGN_ACCESS 1
#elif defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC)
/* Unaligned access is too slow on a PowerPC (maybe?) */
#define ALIGN_ACCESS 1
#elif defined(__i386__) || defined(__x86_64__) || \
defined(_M_IX86) || defined(_M_X64)
/* x86 / x64 are fairly forgiving */
#define ALIGN_ACCESS 0
#else
#warning "Unsupported architecture"
#define ALIGN_ACCESS 1
#endif
请注意,未对齐访问的速度取决于它跨越的边界。例如,如果访问跨越 4k 页边界,则速度会慢很多,并且可能存在其他边界导致速度更慢。即使在 x86 上,一些未对齐的访问也不会由处理器处理,而是由操作系统内核处理。那是慢得令人难以置信。
也不能保证未来(或当前)的实现不会突然改变未对齐访问的性能特征。这已经发生了过去发生的和将来可能发生的; PowerPC 601 非常宽容未对齐的访问,但 PowerPC 603e 则不然。
使事情变得更加复杂的是,您编写的用于进行未对齐访问的代码在跨平台的实现上会有所不同。例如,在 PowerPC 上,它被简化为:x << 32
and x >> 32
总是 0 如果x
是 32 位的,但是在 x86 上你就没有这样的运气了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)