5

在 snappy 的内部,有一个条件编译部分选择取消引用 reinterpret_cast'ed指针作为在已知支持此类操作的架构上读取和写入可能未对齐的 16、32 和 64 位整数的最佳实现(如x86)。其他架构的后备方案是使用基于memcpy 的实现

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

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

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

4

2 回答 2

4

在不知道最初编写该代码的程序员的情况下,我怀疑您能否获得真正权威的答案。

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

虽然智能的现代编译器会优化 . memcpy,但旧的编译器可能不会。一致的性能对于这个库来说非常重要,所以他们似乎牺牲了一些正确性(因为它reinterpret_cast似乎是潜在的 UB),以支持在更广泛的编译器中获得更一致的结果。

于 2014-08-19T05:44:42.030 回答
-1

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

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

就个人而言,我会将安全方法实现为 4 字节的轮班加载。

于 2014-02-10T10:24:05.383 回答