内存移动的性能与memcpy相比是两倍?



我已经在memmove和memcpy有什么区别?中看到了接受答案中指出的差异,它说memmove might be very slightly slower than memcpy

我们可以通过执行以下操作来实现memmove的替代方案:分配一个临时缓冲区,然后memcpy两次(src -> tmp,tmp -> dest(。我的问题是:哪种方式更快,memmove或替代方案?

来自 http://en.cppreference.com/w/cpp/string/byte/memmove

尽管指定"好像"使用了临时缓冲区,但此函数的实际实现不会产生双重复制或额外内存的开销。对于少量计数,它可以加载并写出寄存器;对于较大的块,一种常见的方法(glibc 和 BSD libc(是,如果目标在源之前开始,则从缓冲区的开头向前复制字节,否则从末尾向后复制字节,当根本没有重叠时,回退到 std::memcpy。

因此,开销很可能是几个条件分支。对于大块来说几乎不值得担心。

但是,值得记住的是,std::memcpy是一个"魔术"函数,是在两种不同类型之间进行转换的唯一合法方式。

在 c++ 中,这是非法的(未定义的行为(:

union {
float a;
int b;
} u;
u.a = 10.0;
int x = u.b;

这是合法的:

float a = 10.0;
int b;
std::memcpy(std::addressof(b), std::addressof(a), size(b));

并做你期望工会做的事情,如果你是一个C程序员。

std::memmove">

可能比std::memcpy稍慢">(强调添加(,因为它必须首先检查源和目标范围是否重叠。在内部,这只是几个指针比较;这样做后,如果没有重叠或目标从源下方开始,它会调用std::memcpy;否则,它会调用从结尾复制到开头的std::memcpy变体。

简而言之,唯一的区别是最初的比较;一旦完成,就像std::memcpy一样。不需要额外的缓冲区并复制所有内容两次。

最新更新