Pat*_*ski 32 c++ memory performance allocation copying
我什么时候可以memcpy使用它获得更好的性能?如何使用它?例如:
float a[3]; float b[3];
Run Code Online (Sandbox Code Playgroud)
是代码:
memcpy(a, b, 3*sizeof(float));
Run Code Online (Sandbox Code Playgroud)
比这快?
a[0] = b[0];
a[1] = b[1];
a[2] = b[2];
Run Code Online (Sandbox Code Playgroud)
Mar*_*ork 58
效率不应该是你关注的问题.
编写干净的可维护代码.
令我困扰的是,如此多的答案表明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();
}
Run Code Online (Sandbox Code Playgroud)
然后比较代码产生:
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
Run Code Online (Sandbox Code Playgroud)
这导致:(手动添加评论)
======= // 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
Run Code Online (Sandbox Code Playgroud)
添加了Timing结果,用于在循环中运行上面的内容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
Run Code Online (Sandbox Code Playgroud)
小智 15
memcpy只有当您复制的对象没有显式构造函数时才可以使用,因为它们的成员(所谓的POD,"普通旧数据").因此,它是确定打电话memcpy的float,但它是错误的,如std::string.
但部分工作已经为您完成了:std::copyfrom <algorithm>专门针对内置类型(可能还有其他所有POD类型 - 取决于STL实现).因此,写入std::copy(a, a + 3, b)与编译器优化之后一样快memcpy,但不易出错.
不要过早地使用像这样的memcpy进行微观优化.使用赋值更清晰,更不容易出错,任何体面的编译器都会生成适当高效的代码.如果且仅当您已经分析了代码并发现分配是一个重要的瓶颈,那么您可以考虑某种微优化,但一般来说,您应该始终在第一个实例中编写清晰,健壮的代码.
使用std::copy().作为g++笔记的头文件:
这个内联函数将尽可能地调用@c memmove.
可能,Visual Studio并没有太大的不同.以正常方式行走,并在您意识到瓶颈后进行优化.在简单副本的情况下,编译器可能已经为您进行了优化.
| 归档时间: |
|
| 查看次数: |
27373 次 |
| 最近记录: |