为什么const int比const int更快?

Roo*_*kie 4 c++ visual-c++

有一天我意外地注意到了这一点,现在决定对它进行广泛的测试.

所以,当我调用一个函数时:

#define Type int
#define Prm const Type &
Type testfunc1(Prm v1, Prm v2, Prm v3, Prm v4, Prm v5, Prm v6, Prm v7, Prm v8, Prm v9, Prm v10){
    return (v1|v2|v3|v4|v5|v6|v7|v8|v9|v10);
}
Run Code Online (Sandbox Code Playgroud)

1亿次:

        for(Type y = 0; y < 10000; y++){
            for(Type x = 0; x < 10000; x++){
                out |= testfunc1(x,y,x,x,y,y,x,y,x,y);
            }
        }
Run Code Online (Sandbox Code Playgroud)

对于类型int,const int而且const int &,我注意到它const intconst int &.(注意:我使用返回值来确保函数不会被优化掉).

为什么会这样?我一直认为添加&实际上会让它更快,但测试反过来说.我知道对于更大的数据类型,它可能会有不同的结果,我没有测试那些,因为我非常肯定结果.

我的测试:

const int: 7.95s
const int &: 10.2s
Run Code Online (Sandbox Code Playgroud)

编辑:我认为这确实是因为我的架构; 我测试了Sint64类型,结果如下:

const Sint64: 17.5s
const Sint64 &: 16.2s
Run Code Online (Sandbox Code Playgroud)

编辑2:或者是吗?测试double类型(64位?),结果让我感到困惑:

const double: 11.28s
const double &: 12.34s
Run Code Online (Sandbox Code Playgroud)

Edit3:更新了循环代码,使我的最新测试与64位类型相匹配.

Ski*_*izz 9

通过&在参数中加入,您将向程序添加更多代码.没有&,序列是:

 push values
 call Function
 pop values <- usually an update to stack pointer
Run Code Online (Sandbox Code Playgroud)

和功能:

 return sp[arg1] | sp[arg2] | etc <- value read direct from stack.
Run Code Online (Sandbox Code Playgroud)

添加'&'可以做到这一点:

 push address of value1
 push address of value2
 etc
 call Function
 pop values <- usually an update to stack pointer
Run Code Online (Sandbox Code Playgroud)

和功能:

 return_value = 0;
 address = sp[arg1]
 or return_value, [address]
 address = sp[arg2]
 or return_value, [address]
 etc
 return return_value
Run Code Online (Sandbox Code Playgroud)

所以,正如你所看到的,&增加了许多.那么为什么要用呢?如果您有一个非常大的对象,则传递指针比将对象复制到堆栈更为理想.

  • 我还要补充一点,以上是一般性描述.优化器可以将值放入寄存器而不是堆栈.IA64编译器也可以将参数放入寄存器中. (3认同)

das*_*ght 7

该结果严重依赖于系统.它表明在您的特定系统上复制引用的值(最有可能实现为指针)比复制整数值的成本更高.这种差异的最可能原因是您的整数需要32位来表示,而您的指针/引用表示需要64位.编辑这并不是说访问整数的成本:获取它们的值需要额外的间接.由于您只传递了两个项目,因此使用缓存会在很大程度上隐藏额外成本,但成本却存在.

但是,对于较大的类型,你绝对正确:将引用传递给大型struct或者vector<...>仍然只需要64位(或者系统上的任何大小),无论您的结构有多少项,或者有多少项你的vector<...>.结构越大,通过价值传递的成本就越高,因此通过将其作为参考来实现节省.

  • 即使指针只需要32位,访问实际的int值也需要一个间接,这可能会解释差异. (3认同)
  • 即使复制`int`比复制地址更昂贵,参考版本也涉及间接内存提取操作,这可能与复制`int`的成本相等. (2认同)