为什么有或没有常量修饰符会使效率相差 4 倍
Why with or without const Modifier make efficiency diff 4 times?
为什么有或没有常量修饰符会使效率相差 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
。少了一个读内存(加载)指令,这就是它执行速度快的原因。
但是,必须注意的是,编译器的行为很聪明,非常聪明,所以你无法猜测它可能应用了什么优化技术。它可能已经删除了所有循环(因为它对编译器来说似乎是无操作的)。
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 什么时候在C++中返回常量引用是个好主意
- 代理对象的常量正确性
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 通过多个头文件使用常量变量
- 在cuda线程之间共享大量常量数据
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 是默认情况下分配给char数组常量的值
- 私有类型的静态常量成员
- 类似枚举的计算常量
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 为什么我可以通过引用修改常量返回
- 如何创建长度由常量参数指定的数组
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 隐式常量/非常量运算符布尔
- 字符串作为常量的效率
- 为什么有或没有常量修饰符会使效率相差 4 倍