为什么不通过引用传递结构一个常见的优化? [英] Why isn't pass struct by reference a common optimization?

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

问题描述

直到今天,我一直认为,如果结构足够大,后者会更快,那么体面的编译器会自动将struct pass-by-value转换为pass-by-reference。据我所知,这似乎是一个没有理智的优化。但是,为了满足我是否真的发生这种情况,我在C ++和 D中创建了一个简单的测试用例,并查看了GCC和Digital Mars D的输出。当所有的函数都添加成员并返回值时,坚持通过值传递32字节的结构体,而不修改结构体传入.C ++版本如下。

  #includeiostream.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<<酒吧;
}

我的问题是,为什么不会这样编译器通过引用而不是实际将所有 int s推入堆栈?



注意:使用的编译器开关:GCC -O2(-O3 inlined foo()。),DMD -O -inline -release。



编辑:显然,在一般情况下语义传递值与传递引用的值将不相同,例如如果涉及复制构造函数或在被调用者中修改原始结构体。然而,在许多现实世界的场景中,语义在可观察的行为方面是相同的。这些是我问的情况。

解决方案

不要忘记在C / C ++编译器需要能仅仅基于函数声明来编译对函数的调用。



由于调用者可能只使用该信息,编译器无法编译函数利用你正在谈论的优化。调用者不能知道函数不会修改任何东西,所以它不能通过ref。由于一些呼叫者可能由于缺乏详细信息而传递价值,因此该函数必须被编译,假设按值传递,并且每个人都需要传递值。



注意即使你将参数标记为' const ',编译器仍然不能执行优化,因为函数可能是撒谎和转移constness(这是允许的并且定义良好,只要传入的对象实际上不是const)。



我认为对于静态函数(或者匿名命名空间中的那些),编译器可能会做出你正在谈论的优化,因为函数没有外部链接。只要函数的地址没有传递给其他程序或存储在指针中,它就不应该从其他代码中调用。在这种情况下,编译器可能具有所有调用者的所有知识,所以我想它可以进行优化。



我不知道是否有任何(实际上,



当然,作为程序员(当使用C ++时)可以强制编译器以尽可能使用 const& 参数执行此优化。我知道你问为什么编译器不能自动做,但我想这是下一个最好的事情。


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;
}

My question is, why the heck wouldn't something like this be optimized by the compiler to pass-by-reference instead of actually pushing all those ints onto the stack?

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

Edit: 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.

解决方案

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).

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).

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天全站免登陆