相关疑难解决方法(0)

为什么memmove比memcpy更快?

我正在研究应用程序中的性能热点,它将50%的时间花在memmove(3)上.应用程序将数百万个4字节整数插入到已排序的数组中,并使用memmove将数据"向右"移位,以便为插入的值腾出空间.

我的期望是复制内存非常快,我很惊讶在memmove上花了这么多时间.但后来我认为memmove很慢,因为它正在移动重叠区域,这必须在紧密的循环中实现,而不是复制大页面的内存.我写了一个小的微基准测试,以确定memcpy和memmove之间是否存在性能差异,期望memcpy能够取胜.

我在两台机器(核心i5,核心i7)上运行我的基准测试,看到memmove实际上比memcpy更快,在旧核心i7上甚至快了两倍!现在我正在寻找解释.

这是我的基准.它用memcpy复制100 mb,然后用memmove移动大约100 mb; 来源和目的地重叠.尝试了源和目的地的各种"距离".每次测试运行10次,打印平均时间.

https://gist.github.com/cruppstahl/78a57cdf937bca3d062c

以下是Core i5的结果(Linux 3.5.0-54-generic#81~precision1-Ubuntu SMP x86_64 GNU/Linux,gcc是4.6.3(Ubuntu/Linaro 4.6.3-1ubuntu5).括号中的数字是源和目的地之间的距离(间隙大小):

memcpy        0.0140074
memmove (002) 0.0106168
memmove (004) 0.01065
memmove (008) 0.0107917
memmove (016) 0.0107319
memmove (032) 0.0106724
memmove (064) 0.0106821
memmove (128) 0.0110633
Run Code Online (Sandbox Code Playgroud)

Memmove实现为SSE优化的汇编代码,从后到前复制.它使用硬件预取将数据加载到缓存中,并将128个字节复制到XMM寄存器,然后将它们存储在目标中.

(memcpy-ssse3-back.S,第1650行)

L(gobble_ll_loop):
    prefetchnta -0x1c0(%rsi)
    prefetchnta -0x280(%rsi)
    prefetchnta -0x1c0(%rdi)
    prefetchnta -0x280(%rdi)
    sub $0x80, %rdx
    movdqu  -0x10(%rsi), %xmm1
    movdqu  -0x20(%rsi), %xmm2
    movdqu  -0x30(%rsi), %xmm3
    movdqu  -0x40(%rsi), %xmm4
    movdqu  -0x50(%rsi), %xmm5
    movdqu  -0x60(%rsi), %xmm6
    movdqu  -0x70(%rsi), %xmm7
    movdqu  -0x80(%rsi), %xmm8
    movdqa  %xmm1, …
Run Code Online (Sandbox Code Playgroud)

c c++ memory performance

88
推荐指数
3
解决办法
2万
查看次数

标签 统计

c ×1

c++ ×1

memory ×1

performance ×1