reinterpret_cast用于未对齐内存访问与memcpy的有效用例?

时间:2014-02-09 18:47:54

标签: c++ clang memcpy reinterpret-cast snappy

在snappy的内部,有一个有条件编译的部分选择dereferencing a reinterpret_cast'ed指针作为在已知支持这种结构的体系结构上对可能未对齐的16,32和64位整数进行读写的最佳实现。操作(如x86)。其他架构的后备是使用memcpy based implementation

我的理解是reinterpret_cast实现表现出未定义的行为,并且clang的未定义行为清理程序会标记它。

令我困惑的是:为什么不使用基于memcpy的实现呢?我希望除了最破碎的编译器之外的所有编译器都使用内在函数来实现这些memcpy调用,因为在编译时已知大小。事实上,我希望在任何现代工具链上都可以使用相同的codegen。

但是,我也认识到,那些知道它们是什么的人写的是时髦的。所以这让我想知道使用reinterpret_cast机制是否还有一些优势,这种机制超过了它的未定义行为。不希望性能依赖于编译器的实现质量?我没有考虑过的其他事情?

2 个答案:

答案 0 :(得分:4)

在不知道编写该代码的程序员的情况下,我怀疑你能得到一个真正权威的答案。

这是我最好的猜测:作者不想依赖于可能的memcpy优化(规范无法保证,即使它是由许多编译器实现的)。另一方面,写reinterpret_cast非常非常可能只产生作者所期望的未对齐访问指令,几乎任何编译器。

虽然聪明的现代编译器会优化memcpy,但旧的编译器可能不会。一致的性能对于这个库来说非常关键,因此它们似乎牺牲了一些正确性(因为reinterpret_cast似乎可能是UB),而是支持在更广泛的编译器集中获得更一致的结果。

答案 1 :(得分:-1)

原因是从未对齐的地址加载int比在复制它然后加载它更快(在x86上)。

未对齐加载的开销约为2倍.memcpy归结为4字节读取,4字节写入(或一次32位写入,具体取决于编译器),然后您仍然需要加载。在最好的情况下,优化器可能会发现读后读取是多余的。

就个人而言,我将安全方法实现为带有移位的4字节加载。

相关问题