我发现自己正在调整一段代码,其中使用 memcpy
复制内存,并且在编译时已知第三个参数(大小)。
调用 memcpy
函数的使用者执行类似以下操作:
template <size_t S>
void foo() {
void* dstMemory = whateverA
void* srcMemory = whateverB
memcpy(dstMemory, srcMemory, S)
}
现在,我原以为
memcpy
内在函数足够聪明,可以意识到这一点:foo<4>()
... 可以将函数中的
memcpy
替换为 32 位整数赋值。然而,我惊讶地发现自己看到了 >2x 的加速:template<size_t size>
inline void memcpy_fixed(void* dst, const void* src) {
memcpy(dst, src, size);
}
template<>
inline void memcpy_fixed<4>(void* dst, const void* src) { *((uint32_t*)dst) = *((uint32_t*)src); }
并将
foo
重写为: template <size_t S>
void foo() {
void* dstMemory = whateverA
void* srcMemory = whateverB
memcpy_fixed<S>(dstMemory, srcMemory)
}
两个测试都是在带有 -O3 的 clang (OS X) 上进行的。对于在编译时已知大小的情况,我真的希望
memcpy
内在函数更智能。我的编译器标志是:
-gline-tables-only -O3 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer
我是不是对 C++ 编译器要求太多了,还是我遗漏了一些编译器标志?
最佳答案
memcpy
与 *((uint32_t*)dst) = *((uint32_t*)src)
不同。
memcpy 可以处理未对齐的内存。
顺便说一句,大多数现代编译器确实用合适的代码发射替换了已知大小的 memcpy。对于小尺寸,它通常会发出 rep movsb
之类的东西,在大多数情况下,它可能不够快。
如果你发现你的特殊情况你获得了 2 倍的速度并且你认为你需要加速它,你可以随意弄脏你的手(有明确的评论)。
关于c++ - memcpy 在编译时已知大小,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30936642/