一些CPU架构(除了x86)不喜欢在未对齐的地址上阅读和写入多字节数,以至于它们在检测到这一点时引发SIGBUS异常,并迫使程序员手动按字节顺序执行所有操作。虽然在需要这种操作的平台上可能什么也做不了,但在允许非对齐访问的平台(如x86)上检查对齐并执行字节操作是愚蠢的。问题是:C/C++编译器是否定义了一个常量来表示对齐要求?
目前,我正在使用这个:
#if defined(_M_IX86) | defined(__i386) | defined(__i386__) | defined(i386) | defined(_X86_)
// Unaligned access is allowed.
#elif defined(_M_X64) | defined(__x86_64__) | defined(__x86_64) | defined(__amd64) | defined(__amd64__) | defined(_M_AMD64)
// Unaligned access is allowed.
#else
#define ALIGNED_ACCESS_ONLY
#endif
字符串
但它看起来太“自制”了:本文并没有指出当前硬件平台的实际属性,只是描述了我自己对x86-32和x86-64的考虑以及这些平台最流行的常量名称。
2条答案
按热度按时间rekjcdws1#
如果您的代码是在配置脚本的帮助下编译的,则可以测试以查看是否需要对齐访问。GNU autoconf有一个功能可以做到这一点:
http://www.gnu.org/software/autoconf-archive/ax_check_aligned_access_required.html
基本上,它编译下面的小程序,运行它,并查看结果:
字符串
xxslljrj2#
我在
memcpy
的实现中看到过一种不需要对此进行任何检查的解决方案。基本上,您开始逐字节复制数据,直到获得所需对齐的地址倍数。在此之后,您可以开始复制字大小的数据块,并使用对齐地址的所有好处(循环展开,矢量化......)。
不过,您将在处理大数据块时获得最佳效果。
显然,
clang
和gcc
都没有定义任何宏来通知未对齐的访问。(gcc/clang -E -dM - < /dev/null -march=native
)。您可能需要考虑的一些想法:
asm
:编写依赖于平台的asm
,以便从非对齐访问加载/存储,尽管它高度依赖于您正在使用的平台。