为什么不通过引用传递结构体共同优化? [英] Why isn't pass struct by reference a common optimization?

查看:175
本文介绍了为什么不通过引用传递结构体共同优化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

直至今日,我一直认为体面的编译器会自动转换结构传递按值传递,通过引用,如果结构是足够大的,后者会更快。以我所知,这似乎是一个没有脑子的优化。然而,为了满足我的好奇心,这是否实际发生,我创建了C ++和Ð一个简单的测试案例,并期待在GCC和数字火星D.两者的输出坚持按值传递32个字节的结构时,在问题的所有功能都被添加了成员​​和返回值,其传递的结构没有改变。在C ++版本在下面。

Up until today, I had always thought that decent compilers automatically convert struct pass-by-value to pass-by-reference if the struct is large enough that the latter would be faster. To the best of my knowledge, this seems like a no-brainer optimization. However, to satisfy my curiosity as to whether this actually happens, I created a simple test case in both C++ and D and looked at the output of both GCC and Digital Mars D. Both insisted on passing 32-byte structs by value when all the function in question did was add up the members and return the values, with no modification of the struct passed in. The C++ version is below.

#include "iostream.h"

struct S {
    int i, j, k, l, m, n, o, p;
};

int foo(S s) {
    return s.i + s.j + s.k + s.l + s.m + s.n + s.o + s.p;
}

int main() {
    S s;
    int bar = foo(s);
    cout << bar;
}

我的问题是,为什么赫克不会像这样由编译器优化,以传递按引用而不是实际推动那些 INT 取值到栈?

请注意:编译器开关使用:GCC -O2(-O3内联富()),DMD -O -release -inline

Note: Compiler switches used: GCC -O2 (-O3 inlined foo().), DMD -O -inline -release.

编辑:很显然,在一般情况下的语义传递按值传递与按引用将是不一样的,比如,如果拷贝构造函数参与或原来的结构也是在被叫方修改。然而,在很多现实世界中,语义将在观察行为上是相同的。这是我要问有关情况。

Obviously, in the general case the semantics of pass-by-value vs. pass-by-reference won't be the same, such as if copy constructors are involved or the original struct is modified in the callee. However, in a lot of real-world scenarios, the semantics will be identical in terms of observable behavior. These are the cases I'm asking about.

推荐答案

不要忘了,在C / C ++编译器需要能够编译仅在函数声明为基础,以一个函数的调用。

Don't forget that in C/C++ the compiler needs to be able to compile a call to a function based only on the function declaration.

由于呼叫者可能只使用这些信息,也没有办法为一个编译器来编译功能带你谈论的优化优势。主叫方可以不知道函数不会修改任何东西,所以它不能由参传递。由于一些呼叫者可以按值传递,由于缺乏详细的信息,该函数有假设传递由值和每个人都需要按值传递进行编译。

Given that callers might be using only that information, there's no way for a compiler to compile the function to take advantage of the optimization you're talking about. The caller can't know the function won't modify anything and so it can't pass by ref. Since some callers might pass by value due to lack of detailed information, the function has to be compiled assuming pass-by-value and everybody needs to pass by value.

请注意,即使您标记的参数为常量',编译器仍然不能进行优化,因为该功能可以撒谎,抛弃常量性(这是允许的和明确的,只要传递的对象其实不是常量)。

Note that even if you marked the parameter as 'const', the compiler still can't perform the optimization, because the function could be lying and cast away the constness (this is permitted and well-defined as long as the object being passed in is actually not const).

我认为,静态函数(或者那些在匿名命名空间),编译器可能会使得你在谈论优化,因为函数没有外部链接。只要函数的地址不传递到某些其他常规或存储于一个指针,它不应该是从其他code调用。在这种情况下,编译器可以将所有的来电者充分了解,所以我想它可以使优化。

I think that for static functions (or those in an anonymous namespace), the compiler could possibly make the optimization you're talking about, since the function does not have external linkage. As long as the address of the function isn't passed to some other routine or stored in a pointer, it should not be callable from other code. In this case the compiler could have full knowledge of all callers, so I suppose it could make the optimization.

我不知道如果有做(其实,我会感到惊讶,如果任何事,因为它可能不能经常使用)。

I'm not sure if any do (actually, I'd be surprised if any do, since it probably couldn't be applied very often).

当然,作为程序员(当使用C ++),你可以强制编译器使用常量和放大器来执行此优化; 参数只要有可能。我知道你问为什么编译器不能自动做到这一点,但我想这是未来最好的事情。

Of course, as the programmer (when using C++) you can force the compiler to perform this optimization by using const& parameters whenever possible. I know you're asking why the compiler can't do it automatically, but I suppose this is the next best thing.

这篇关于为什么不通过引用传递结构体共同优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆