某些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的考虑以及这些平台最常用的常量名称。
答案 0 :(得分:1)
我在技术上并没有回答你提出的问题,但我提出了一个解决方法,以防你的问题的答案是否定的。
如果您的代码是在configure脚本的帮助下编译的,则可以测试是否需要对齐访问。 GNU autoconf具有执行此操作的功能:
http://www.gnu.org/software/autoconf-archive/ax_check_aligned_access_required.html
基本上它编译下面的小程序,运行它,并查看结果:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* string = malloc(40);
int i;
for (i=0; i < 40; i++)
{
string[[i]] = i;
}
{
void* s = string;
int* p = s+1;
int* q = s+2;
if (*p == *q) { return 1; }
}
return 0;
}
答案 1 :(得分:0)
我在memcpy
的实现中看到的解决方案不需要任何检查。基本上,您开始每个字节复制数据字节,直到达到所需对齐的地址倍数
之后,您可以开始复制字大小的数据块,并使用对齐的地址(循环展开,矢量化,...)带来的所有好处。
尽管如此,你可以利用大块数据充分利用它。
显然,clang
和gcc
都没有定义任何宏来通知未对齐的访问。 (gcc/clang -E -dM - < /dev/null -march=native
)。
您可能需要考虑的一些想法:
asm
:编写与平台相关的asm
来加载/存储与未对齐访问的对象,尽管它在很大程度上取决于您正在使用的平台。答案 2 :(得分:-3)
OP:C / C ++编译器是否定义了一个表示对齐要求的常量?
是。 max_align_t
是最大对齐要求的类型。
如果sizeof(max_align_t) > 1
,则需要进行一些对齐。
在C11之前,请参阅Compiler constant indicating memory alignment requirement