繁体   English   中英

memmove的性能是memcpy的两倍?

[英]Performance of memmove compared to memcpy twice?

我已经看到了接受的答案中指出的区别: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 无需额外的缓冲区,无需复制所有内容两次。

Memcpy通常更快,因为它不假定目标和源可能重叠。

因此,如果尝试使用memcpy将字符串abcd从位置X复制到X+2 ,则可能会得到类似的结果

X: A B C D

在memcpy之后

X+2 A B A A

而memmove可以确保您不会丢失任何内容,因为它使用中间缓冲区存储原始字符串。

另一方面,您可以对源和目标使用限定符restrict ,这样您可以告诉记忆源和目标不重叠,并且像记忆可以在使用该限定符的情况下选择其他更快的算法。

有关详细信息,请参见此处

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM