C/C++中Memcopy的性能成本

21

每当我写代码时,我总是考虑性能影响。我经常想知道,在性能方面使用memcopy相对于其他函数的“成本”是多少?

例如,我可能正在将一系列数字写入静态缓冲区并集中一个帧在缓冲区内,为了保留该帧,一旦到达缓冲区的末尾,我可能会将其全部memcopy到开头,或者我可以实现一种算法来分摊计算。


11
你是否曾超越思考表现,对其进行了测量? - High Performance Mark
我有,但不是用于memcopy。 - Cenoc
6
一直只考虑代码的性能是写出糟糕(而且也许很慢)代码的好方法。 - anon
1
memcpy可以进行优化,但这需要使用汇编语言来利用处理器特定的功能,并针对特定情况。在考虑优化memcpy时,必须首先问为什么要复制内存。首先使用智能指针和引用。 - Thomas Matthews
@Thomas:非常小心,复制和引用都有它们的目的。将引用作为优化可能非常危险(就像我吃过的亏一样...) - stefaanv
5个回答

28

memcpy通常优化以最大化大型复制的内存带宽。当然,避免完全复制才是最快的方法,对于固定大小的短型复制,使用直接赋值可能更快,因为memcpy有额外代码来处理奇数长度。

但是,当你需要复制一块内存时,很难击败memcpy。它高度可移植,大多数编译器都会尽力使其快速运行,无论是使用SIMD指令还是内联。


2
在C ++中应避免使用memcpy,因为它是一种“愚蠢”的复制方式,可能会导致糟糕的结果。应该使用赋值运算符/复制构造函数作为替代方案。此外,首先应该运行一个简介以确定它是否是问题所在。 - Puppy
20
许多 C++ 程序都处理“愚蠢”的数据,这在 C++ 标准中被称为“纯粹的旧数据”,并且可以安全地使用 memcpy。根据我的经验,那些不具备 POD 的程序更适合用高级语言编写。 - Ben Voigt
4
是的。你可以使用memcpy并在非POD类型上完全破坏你的程序。或者,你可以使用赋值运算符,对于POD类型最终会导致memcpy,并且对于非POD类型,程序将正常工作。 - Puppy
3
赋值运算符对于POD类型不会导致调用memcpy,它将产生二进制图像,这与使用memcpy的结果相同,但没有任何优化。更好的方法是使用std::copy,它将为非POD类型执行正确的操作,然后使用类型特征来专门调用优化的块复制,如memcpy,从而保证安全性。 - Ben Voigt

6
考虑性能影响是可以的,但不要过于分心,远离写好干净代码的真正目标。如果你倾向于即使知道更好的做法也会痴迷于性能问题,请试着关注更高层次的影响,忽略像memcpy这样的逐位操作,你可以相信编译器和库作者进行优化。
通常应避免这种低级别的过早优化,因为它会消耗你的时间,其影响将波及整个程序,并且没有测量,你不能指望获得任何性能提升。

1

首先,只有在内存复制是您的瓶颈时(这确实是一个罕见的情况),您才应考虑性能。

其次,memcpy 是使用汇编实现的(请参见 memcpy.asm),我想它是最快的内存复制解决方案。

另外要提到的是,在 C++ 中通常应避免使用原始的 memcpy 调用,尝试使用更抽象的包装和例程。


简单的赋值可以使用CPU寄存器实现,但不需要使用memcpy。如果赋值太大,编译器会自动退回到memcpy,因此最好使用赋值(在适用的情况下...)。 - MindTailor

1

memcpy() 函数将源内存中的内容复制到目标内存中。复制操作显然是与源中元素数量成线性关系的。什么样的元素大小最优取决于机器。无论如何,根据操作的上下文,许多编译器优化黑科技都可以应用。在 C++ 中,通常更明智的做法是避免使用 memcpy,而是使用赋值或复制构造函数。


2
在现代架构中,考虑到内存架构和缓存效应,复制几乎肯定不是线性的。memcpy和复制构造函数是在比较苹果和橙子。 - Johan Kotlinski

1
考虑麦考密克的书《代码大全》。从中不吝窃取的经验如下:
  1. 算法改进通常能够带来最大的性能回报。

  2. 简单语句可以让编译器有效优化。它们的成本低,通常会提高可读性。它们是一种低成本默认的“应该”的选择。

正如提到的,memcpy已经被调整过了,对于较大的内存块通常非常有效。那么如果情况要求保留数据,为什么要避免使用它呢?

总的来说,不要无缘无故地进行优化。假设您针对大型数据集编写报告。在这种情况下,没有用户期望立即得到响应。他们启动任务后去拿点心。所以,如果您的代码运行时间为10分钟或3分钟,对他们来说并没有关系。他们不会注意到。而且...他们付你的薪水。

程序员优化是巨大的前期成本。因此,只在必要时才花费这些成本。


1
实际上,这是史蒂夫·麦康奈尔的《代码大全》。 - Chris Pitman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接