为什么有或没有常量修饰符会使效率相差 4 倍

Why with or without const Modifier make efficiency diff 4 times?

本文关键字:效率 常量 为什么      更新时间:2023-10-16

为什么有或没有常量修饰符会使效率相差 4 倍?这段代码需要大约 16 秒才能在我的 PC 中完成。但是如果我做一个小的更改,比如将 mod 声明为 const int 或移动主体中的 mod 声明,或者将 i 更改为 int 类型,执行时间减少到 4 秒。(我使用带有默认参数的 g++ 编译此代码)

这是此代码的汇编代码,左侧部分使用非 const int mod 生成,另一部分使用 const int mod 声明生成。

只有当我声明 i 为 long 并且 for 循环中的运算符是 '%' 时,才会出现大效率。否则,性能仅相差约 10%。

// const int mod = 1000000009; 
int mod = 1000000009; 
int main(){
    // int mod = 1000000009; 
    int rel = 0;
    for(long long i=1e9; i<2*(1e9); i++){
        rel = i % mod;
    }
    return 0;
}

因为当你添加 const 时,编译会把它改成常量值并写入汇编代码中,但是当你不添加 const 时,该值会被加载到寄存器中,所以每次必须使用它时都必须查询它

将内存中的mod值加载到寄存器中时,生成的汇编代码是不同的。

例如,这是使用基于 x64 的处理器的 Visual Studio 2013 编译器时获得的结果:

对于int mod = 1000000009

mov  eax,dword ptr ds:[xxxxxxxxh]  ;  xxxxxxxxh = &mod
cdq
push edx
push eax

对于const int mod = 1000000009

push 0
push 3B9ACA09h  ;  3B9ACA09h = 1000000009

const变量可能会也可能不会占用堆栈上的空间 - 这取决于编译器。但是,在大多数情况下,常量变量的用法将被其常量值所取代。考虑:

const int size = 100;
int* pModify = (int*)&size;
*pModify = 200;
int Array[size];

当你使用*pModify时,它将呈现200数组的大小将仅100元素(忽略允许可变大小数组的新功能的编译器扩展)。只是因为编译器用[100]替换了[size]。当你使用size时,它大多只是100

在那个循环中,%mod只是被替换为%1000000009。少了一个读内存(加载)指令,这就是它执行速度快的原因。

但是,必须注意的是,编译器的行为很聪明,非常聪明,所以你无法猜测它可能应用了什么优化技术。它可能已经删除了所有循环(因为它对编译器来说似乎是无操作的)。