编译器可以考虑的一个小小可能性
这段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$, 99 ; 00000063H
mov DWORD PTR _y$, 77 ; 0000004dH
mov eax, DWORD PTR _x$
add eax, 1
and eax, -2147483585 ; 8000003fH
jns SHORT $L69607
dec eax
or eax, -64 ; ffffffc0H
inc eax
mov DWORD PTR _x$, eax
mov eax, DWORD PTR _y$
add eax, 1
xor edx, edx
mov ecx, 64 ; 00000040H
div ecx
mov DWORD PTR _y$, edx
mov edx, DWORD PTR _x$
add edx, 1
and edx, -2147483617 ; 8000001fH
jns SHORT $L69608
dec edx
or edx, -32 ; ffffffe0H
inc edx
mov DWORD PTR _x$, edx
mov eax, DWORD PTR _y$
add eax, 1
xor edx, edx
mov ecx, 32 ; 00000020H
div ecx
mov DWORD PTR _y$, edx
mov DWORD PTR _mode_u$, 32 ; 00000020H
mov DWORD PTR _mode_i$, 32 ; 00000020H
mov eax, DWORD PTR _x$
add eax, 1
cdq
idiv DWORD PTR _mode_i$
mov DWORD PTR _x$, edx
mov eax, DWORD PTR _y$
add eax, 1
xor edx, edx
div DWORD PTR _mode_u$
mov DWORD PTR _y$, edx
mov DWORD PTR _mode_u$, 11 ; 0000000bH
mov DWORD PTR _mode_i$, 12 ; 0000000cH
mov eax, DWORD PTR _x$
add eax, 1
cdq
idiv DWORD PTR _mode_i$
mov DWORD PTR _x$, edx
mov eax, DWORD PTR _y$
add eax, 1
xor edx, edx
div DWORD PTR _mode_u$
mov DWORD PTR _y$, edx
mov eax, DWORD PTR _x$
mov esp, ebp
pop ebp
ret 0
?test_int_mod@@YAHXZ ENDP ; test_int_mod
其中不能针对mode_u变量的值做优化(gcc也类似问题),但对大家自己的特定编译器或虚拟机解释器在编译时则可考虑加入判断mode_u是不是2的次幂来做不同的处理的代码.
但对于边解释边运行的机制来说:这样一来判断能力mode_u是不是2的次幂 又要多出代码耗时了.
因此只能考虑编译型或伪编译性执行采用这样的建议. 不用细看,基于数值特征的优化基本上是费力不讨好。把这些交给程序员在他们真正需要优化的地方自己去解决更好。比如用移位和位逻辑运算代替乘除和求余。
下面这样的代码你认为应该被优化掉吗
int i, t1, t2;
i = 0;
t1 = i*3;
t2 = t1 * 4; :)
你认为以下代码:
#include <stdio.h>
int main()
{
int i,j;
for(i=0,j=0;i<10000;i++)
j+=i;
return 0;
}
应该被优化为以下吗?
.globl main
main:
xorl %eax, %eax
ret
2,3楼的观点是正确的!
我表述的有问题.
意思不是优化掉代码,而是根据输入值分支到相对合适的模块.
[ 本帖最后由 system888net 于 2008-5-6 23:57 编辑 ] 原帖由 Wind-Son 于 2008-5-6 22:31 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
不用细看,基于数值特征的优化基本上是费力不讨好。把这些交给程序员在他们真正需要优化的地方自己去解决更好。比如用移位和位逻辑运算代替乘除和求余。
下面这样的代码你认为应该被优化掉吗
int i, t1, t2 ...
:smile:
可以优化为:
nt i, t1, t2;
i = 0;// ori=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
当然,这种类型优化体系结构相关 原帖由 cjaizss 于 2008-5-7 00:37 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
我倒,为了一个乘法,居然加了个条件分支.........
有这么做的编译器?除了bt,我想不出来别的词语形容。
你说直接优化为
int i=0,t1=0,t2=0;
我还信。
:-)
nt i, t1, t2;
i = 0;// ori=input();
if(i==0)//对于用户i=input(); 多次输入的时候,i=0的特例虚拟机的确可以快速出结果.
{
t1=0;
t2=0;
}
else
{
//假如这里有多次的运算..., 对于i=0用户的感觉虚拟机太苯了
t1 = i*3;
t2 = t1 * 4;
} 原帖由 cjaizss 于 2008-5-7 00:47 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
另外,X86上对于这种乘特殊数(一般比较小的数),可能会采取用寻址来实现乘法。
比如:
leal (%eax,%eax,2), %eax
其实就是为了实现乘3
当然,这种类型优化体系结构相关
这个观点同意 原帖由 system888net 于 2008-5-7 00:48 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
:-)
nt i, t1, t2;
i = 0;// ori=input();
if(i==0)//对于用户i=input(); 多次输入的时候,i=0的特例虚拟机的确可以快速出结果.
{
t1=0;
t2=0;
}
else
{
//假如这里有多次的运算... ...
:shock: :shock: :shock:
页:
[1]
2