这些整数是否未对齐,我需要关心吗?

4

我有一些代码,可以从任意地址的字节数组中解释多字节宽度整数。

std::vector<uint8> m_data; // filled with data
uint32 pos = 13;           // position that might not be aligned well for 8 byte integers
...

uint64 * ptr = reinterpret_cast<uint64*>(m_data.data() + pos);
*ptr = swap64(*ptr);  // (swaps endianness)

这段代码是否有对齐问题?如果有,那么这是一个严重的问题吗,还是可以忽略因为惩罚很小?


2
为什么不进行测量和基准测试呢?做几百万次这样的操作,然后与做几百万次对齐访问进行比较。 - Some programmer dude
1
如果pos始终可被8整除(或更准确地说,data+pos可被8整除),则对于错误对齐不会有惩罚。但我使用SPD。请测量它并将其与将数据复制到临时变量中的成本进行比较。此外,在某些旧平台上(例如sun sparc),在错误对齐的地址上访问变量会导致崩溃。但我相信大多数平台芯片+操作系统在发生这种情况时会进行适当的修复。那个修复的成本是未知的。请测量它。 - selbie
还要注意,在执行原子操作和其他类型的内置函数时,对齐非常重要。这些操作可能会给你带来很大的困扰。 - Athos vk
2个回答

2

请使用memcpy代替:

uint64_t x;
memcpy(&x, m_data.data()+pos, sizeof(uint64_t));
x = swap(x);
memcpy(m_data.data()+pos, &x, sizeof(uint64_t));

它有两个好处:
  • 避免了严格别名违规 (将uint8_t缓冲区读取为uint64_t引起的)
  • 您完全不必担心对齐问题(需要关注对齐问题,因为即使在x86上,如果编译器自动矢量化您的代码,也可能会崩溃)
当前编译器足够优秀,会做正确的事情 (例如,你的代码不会变慢,memcpy被识别并处理得很好)。

1
一些架构需要读取数据时进行对齐才能正常工作。如果对齐不正确,它们会抛出处理器信号。
根据平台的不同,可能会:
  1. 导致程序崩溃
  2. 导致使用未对齐读取重新运行。(性能受损)
  3. 正常工作
进行性能测试是一个好的开始,并检查目标平台的操作系统规范是明智的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接