[英]Do C++ compilers optimize pass by const reference POD parameters into pass by copy?
考虑以下:
struct Point {double x; double y;};
double complexComputation(const& Point p1, const Point& p2)
{
// p1 and p2 used frequently in computations
}
编译器是否将pass-by-reference优化为pass-by-copy以防止频繁解除引用? 换句话说,将complexComputation
转换为:
double complexComputation(const& Point p1, const Point& p2)
{
double x1 = p1.x; double x2 = p2.x;
double y1 = p1.y; double y2 = p2.y;
// x1, x2, y1, y2 stored in registers and used frequently in computations
}
由于Point是一个POD,通过在调用者的背后制作副本可以没有副作用,对吗?
如果是这种情况,那么我总是可以通过const引用传递POD对象,无论多小,都不必担心最佳传递语义。 对?
编辑:我特别感兴趣的是GCC编译器。 我想我可能要编写一些测试代码并查看ASM。
如果需要,您的编译器绝对可以将Point成员变量提升到寄存器 但是,这与将函数调用本身转换为pass by value的编译器不同。
您应该检查生成的程序集以查看正在执行的优化。
而FWIW,我使用的一般规则是在可能的情况下通过const引用按值和所有类/ UDT(POD或不是POD)传递所有原始类型,并让编译器找出最好的事情。 我们不应该担心编译器正在做什么的细节,它比我们聪明得多。
有2个问题。
首先,编译器不会将pass-by-ref转换为pass-by-value,特别是如果complexComputation
不是static
(即可以由外部对象使用)。
原因是API兼容性。 对于CPU,没有“引用”这样的东西。 编译器将引用转换为指针。 参数在堆栈上或通过寄存器传递,因此调用complexComputation
的代码可能会被调用为(假设double
的长度为4):
str x1, [r7, #0x20]
str y1, [r7, #0x24]
str x2, [r7, #0x50]
str y2, [r7, #0x54]
push r7, #0x20 ; push address of p1 onto the stack
push r7, #0x50 ; push address of p2 onto the stack
call complexComputation
只有8个字节被压入堆栈。
另一方面,通过复制将整个结构推送到堆栈,因此汇编代码看起来像
push x1 ; push a copy of p1.x onto the stack
push y1 ; push a copy of p1.y onto the stack
push x2 ; push a copy of p2.x onto the stack
push y2 ; push a copy of p2.y onto the stack
call complexComputation
请注意,此时16个字节被压入堆栈,内容是数字,而不是指针。 如果complexComputation
更改其参数传递语义,则输入将变为垃圾并且您的程序可能会崩溃。
另一方面,优化
double complexComputation(const Point& p1, const Point& p2) {
double x1 = p1.x; double x2 = p2.x;
double y1 = p1.y; double y2 = p2.y;
// x1, x2, y1, y2 stored in registers and used frequently in computations
}
因为编译器可以识别经常使用的变量并将它们存储到保留寄存器(例如ARM架构中的r4~r13,以及许多sXX / dXX寄存器)以便更快地访问,所以可以轻松完成。
毕竟,如果你想知道编译器是否做了什么,你总是可以反汇编结果对象并进行比较。
我不能代表每个编译器,但一般的答案是否定的 。 它不会进行优化。
请参阅GOTW#81 ,了解如何在C ++中转换为const
不会像某些人想象的那样影响优化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.