gpt4 book ai didi

c++ - 在什么情况下我应该在 C++ 中使用 memcpy 而不是标准运算符?

转载 作者:IT老高 更新时间:2023-10-28 12:42:10 25 4
gpt4 key购买 nike

我什么时候可以使用 memcpy 获得更好的性能,或者我如何从使用它中受益?例如:

float a[3]; float b[3];

是代码:

memcpy(a, b, 3*sizeof(float));

比这个更快

a[0] = b[0];
a[1] = b[1];
a[2] = b[2];

最佳答案

效率不应该是您关心的问题。
编写干净的可维护代码。

这么多答案表明 memcpy() 效率低下,这让我很困扰。它被设计成最有效的内存块复制方式(用于 C 程序)。

所以我写了以下内容作为测试:

#include <algorithm>

extern float a[3];
extern float b[3];
extern void base();

int main()
{
base();

#if defined(M1)
a[0] = b[0];
a[1] = b[1];
a[2] = b[2];
#elif defined(M2)
memcpy(a, b, 3*sizeof(float));
#elif defined(M3)
std::copy(&a[0], &a[3], &b[0]);
#endif

base();
}

然后对比代码产生:

g++ -O3 -S xr.cpp -o s0.s
g++ -O3 -S xr.cpp -o s1.s -DM1
g++ -O3 -S xr.cpp -o s2.s -DM2
g++ -O3 -S xr.cpp -o s3.s -DM3

echo "=======" > D
diff s0.s s1.s >> D
echo "=======" >> D
diff s0.s s2.s >> D
echo "=======" >> D
diff s0.s s3.s >> D

这导致:(手动添加的评论)

=======   // Copy by hand
10a11,18
> movq _a@GOTPCREL(%rip), %rcx
> movq _b@GOTPCREL(%rip), %rdx
> movl (%rdx), %eax
> movl %eax, (%rcx)
> movl 4(%rdx), %eax
> movl %eax, 4(%rcx)
> movl 8(%rdx), %eax
> movl %eax, 8(%rcx)

======= // memcpy()
10a11,16
> movq _a@GOTPCREL(%rip), %rcx
> movq _b@GOTPCREL(%rip), %rdx
> movq (%rdx), %rax
> movq %rax, (%rcx)
> movl 8(%rdx), %eax
> movl %eax, 8(%rcx)

======= // std::copy()
10a11,14
> movq _a@GOTPCREL(%rip), %rsi
> movl $12, %edx
> movq _b@GOTPCREL(%rip), %rdi
> call _memmove

添加了在 1000000000 的循环中运行上述内容的计时结果。

   g++ -c -O3 -DM1 X.cpp
g++ -O3 X.o base.o -o m1
g++ -c -O3 -DM2 X.cpp
g++ -O3 X.o base.o -o m2
g++ -c -O3 -DM3 X.cpp
g++ -O3 X.o base.o -o m3
time ./m1

real 0m2.486s
user 0m2.478s
sys 0m0.005s
time ./m2

real 0m1.859s
user 0m1.853s
sys 0m0.004s
time ./m3

real 0m1.858s
user 0m1.851s
sys 0m0.006s

关于c++ - 在什么情况下我应该在 C++ 中使用 memcpy 而不是标准运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4544804/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com