繁体   English   中英

C ++编译器是否通过const引用POD参数优化传递?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM