编译器可以考虑的一个小小可能性
这段c代码
- int test_int_mod()
- {
- unsigned int mode_u;
- int mode_i;
- int x;
- unsigned int y;
- x=99;
- y=77;
- x=(x+1)%64;
- y=(y+1)%64;
- x=(x+1)%32;
- y=(y+1)%32;
- mode_u=32;
- mode_i=32;
- x=(x+1)%mode_i;
- y=(y+1)%mode_u;
- mode_u=11;
- mode_i=12;
- x=(x+1)%mode_i;
- y=(y+1)%mode_u;
- return(x);
- }
复制代码
在VC6.0下被编译成了如下:
- ?test_int_mod@@YAHXZ PROC NEAR ; test_int_mod
- push ebp
- mov ebp, esp
- sub esp, 16 ; 00000010H
- mov DWORD PTR _x$[ebp], 99 ; 00000063H
- mov DWORD PTR _y$[ebp], 77 ; 0000004dH
- mov eax, DWORD PTR _x$[ebp]
- add eax, 1
- and eax, -2147483585 ; 8000003fH
- jns SHORT $L69607
- dec eax
- or eax, -64 ; ffffffc0H
- inc eax
- mov DWORD PTR _x$[ebp], eax
- mov eax, DWORD PTR _y$[ebp]
- add eax, 1
- xor edx, edx
- mov ecx, 64 ; 00000040H
- div ecx
- mov DWORD PTR _y$[ebp], edx
- mov edx, DWORD PTR _x$[ebp]
- add edx, 1
- and edx, -2147483617 ; 8000001fH
- jns SHORT $L69608
- dec edx
- or edx, -32 ; ffffffe0H
- inc edx
- mov DWORD PTR _x$[ebp], edx
- mov eax, DWORD PTR _y$[ebp]
- add eax, 1
- xor edx, edx
- mov ecx, 32 ; 00000020H
- div ecx
- mov DWORD PTR _y$[ebp], edx
- mov DWORD PTR _mode_u$[ebp], 32 ; 00000020H
- mov DWORD PTR _mode_i$[ebp], 32 ; 00000020H
- mov eax, DWORD PTR _x$[ebp]
- add eax, 1
- cdq
- idiv DWORD PTR _mode_i$[ebp]
- mov DWORD PTR _x$[ebp], edx
- mov eax, DWORD PTR _y$[ebp]
- add eax, 1
- xor edx, edx
- div DWORD PTR _mode_u$[ebp]
- mov DWORD PTR _y$[ebp], edx
- mov DWORD PTR _mode_u$[ebp], 11 ; 0000000bH
- mov DWORD PTR _mode_i$[ebp], 12 ; 0000000cH
- mov eax, DWORD PTR _x$[ebp]
- add eax, 1
- cdq
- idiv DWORD PTR _mode_i$[ebp]
- mov DWORD PTR _x$[ebp], edx
- mov eax, DWORD PTR _y$[ebp]
- add eax, 1
- xor edx, edx
- div DWORD PTR _mode_u$[ebp]
- mov DWORD PTR _y$[ebp], edx
- mov eax, DWORD PTR _x$[ebp]
- mov esp, ebp
- pop ebp
- ret 0
- ?test_int_mod@@YAHXZ ENDP ; test_int_mod
复制代码
其中不能针对mode_u变量的值做优化(gcc也类似问题),但对大家自己的特定编译器或虚拟机解释器在编译时则可考虑加入判断mode_u是不是2的次幂来做不同的处理的代码.
但对于边解释边运行的机制来说:这样一来判断能力mode_u是不是2的次幂 又要多出代码耗时了.
因此只能考虑编译型或伪编译性执行采用这样的建议.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
不用细看,基于数值特征的优化基本上是费力不讨好。把这些交给程序员在他们真正需要优化的地方自己去解决更好。比如用移位和位逻辑运算代替乘除和求余。
下面这样的代码你认为应该被优化掉吗
int i, t1, t2;
i = 0;
t1 = i * 3;
t2 = t1 * 4;
你认为以下代码:
复制代码
应该被优化为以下吗?
复制代码
2,3楼的观点是正确的!
我表述的有问题.
意思不是优化掉代码,而是根据输入值分支到相对合适的模块.
[ 本帖最后由 system888net 于 2008-5-6 23:57 编辑 ]
可以优化为:
nt i, t1, t2;
i = 0; // or i=input();
if(i==0)
{
t1=0;
t2=0;
}
else
{
t1 = i * 3;
t2 = t1 * 4;
}
对于虚拟机是有意义的
我倒,为了一个乘法,居然加了个条件分支.........
有这么做的编译器?除了bt,我想不出来别的词语形容。
你说直接优化为
int i=0,t1=0,t2=0;
我还信。
另外,X86上对于这种乘特殊数(一般比较小的数),可能会采取用寻址来实现乘法。
比如:
leal (%eax,%eax,2), %eax
其实就是为了实现乘3
当然,这种类型优化体系结构相关
nt i, t1, t2;
i = 0; // or i=input();
if(i==0) //对于用户i=input(); 多次输入的时候,i=0的特例虚拟机的确可以快速出结果.
{
t1=0;
t2=0;
}
else
{
//假如这里有多次的运算..., 对于i=0用户的感觉虚拟机太苯了
t1 = i * 3;
t2 = t1 * 4;
}
这个观点同意