2012-02-17 54 views
2

我目前正在尝试构建一个代码,该代码适用于各种机器,从手持式口袋和传感器到数据中心中的大型服务器。检测目标CPU上对齐的内存要求

这些体系结构之间的(许多)差异之一是对齐内存访问的要求。

“标准”x86 CPU上不需要对齐内存访问,但许多其他CPU需要它,并且在不遵守规则时会产生异常。

到目前为止,我一直在通过使用packed属性(或pragma)强制编译器对已知有风险的特定数据访问进行谨慎处理。它工作正常。

问题是,编译器非常谨慎,以至于在这个过程中大量的性能丢失了。因为性能很重要,所以我们最好重写代码的某些部分以专门处理严格对齐的cpus。另一方面,这样的代码在支持未对齐内存访问的cpus(比如x86)上会更慢,所以我们希望在需要严格对齐内存访问的cpus上使用它只有

现在问题: 如何在编译时检测到目标架构需要严格对齐的内存访问? (或其他方式)

回答

4

没有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上,一些未对齐的访问也不由处理器处理,而是由OS内核处理。那是非常慢。

也不保证未来(或当前)实现不会突然改变未对齐访问的性能特征。这已发生在过去和未来可能发生; PowerPC 601是非常宽容的未对齐访问,但PowerPC 603e不是。

使事情变得更加复杂的事实是,为编写不对齐的访问而编写的代码在不同平台的实现中会有所不同。例如,在PowerPC上,通过x << 32x >> 32始终为0,如果x为32位,但在x86上没有这样的运气,则可以简化PowerPC。

+0

有趣。这确实是我开始这样做的方式,但显然,我不知道所有的架构在那里......顺便说一句,没有不幸的是,我没有“直接”访问所有这些架构,所以我必须猜测提前解决大部分问题,以避免在代码维护阶段出现太多并发症。 – Cyan 2012-02-18 00:52:31

+0

您无法了解所有架构,但声称支持您无法访问的架构是不负责任的,至少如果您正在编写C语言。 – 2012-02-18 01:55:02

+0

我完全同意。我的目标主要是为其他人定制软件包,以便为其自己的目标架构进行定制。准备得越好,下游越容易。但正如你所说,我不能“声称”完全验证它。尽管如此,与“我不在乎”相比,优秀的软件设计仍然具有优势。 – Cyan 2012-02-20 10:03:09

4

无论如何,编写严格内存对齐的代码是一个好主意。即使在允许未对齐访问的x86系统上,未对齐的读/写也会导致两次内存访问,并且某些性能将会丢失。编写适用于所有CPU架构的高效代码并不困难。要记住的简单规则是指针必须与您正在阅读或书写的对象的大小对齐。例如如果写入一个DWORD,则(dest_pointer & 3 == 0)。使用诸如“UNALIGNED_PTR”类型的拐杖会导致编译器生成低效的代码。如果你有大量必须立即工作的遗留代码,那么使用编译器来“修复”这种情况是有道理的,但如果它是你的代码,那么从一开始就写它来在所有系统上工作。

+0

不幸的是,有些情况下我没有选择,并且提供了一个指针,它可能*不能对齐。 – Cyan 2012-02-18 00:50:27

+0

您可以测试指针是否与此对齐: if((int)pointer&objectsize-1){take unaligned action} – BitBank 2012-02-18 00:52:27

+0

当然,但测试本身太慢了。每次更好地访问一个字节的内存并从这些字节重建数据。很明显,这个结论在支持未对齐访问的CPU(如x86)上完全错误。 – Cyan 2012-02-18 00:59:03