想在软件中用点内嵌汇编,提升一下软件的档次 ( 积分: 50 )

  • 主题发起人 主题发起人 我爱PASCAL
  • 开始时间 开始时间
test 9 代码还可以优化,有冗余的操作。麻烦kinneng, 再测试看看,速度是否有提高?
asm
mov ECX, [EAX]
mov [EAX], [EDX]
mov [EDX], ECX
end;
 
楼主倒是挺实在的
 
这种优化一点意义也没有,除非你的程序每秒要处理几万个以上的交换
 
我的程序每秒处理上亿个交换。
非常感谢kinneng的测试结果,不过我觉得结果是不是太慢了。
我的还带运算,每秒上亿次左右。是不是用过程调用太慢。
你的对比都是建立在调用过程的基础上,而我的循环是在For
循环内,没过程,这样的话不需要压栈出栈,能不能更快。
就像C中可以将tmp定义为register变量。就可以了。
 
http://www.51zhan.com 最好的网址站
 
to ufo!
你的CPU是自制的吗?还是想考考我的汇编基础,mov [EAX], [EDX]这种两个操作数都是地
址指针的指令我没见过。

我的机确实慢,是P166的二手手提机,有USB接蓝牙,连接手机,就可以在大街上上dfw,
也可以看股票,慢是慢了点,胜在可移动。
 
只是为了对比,就不要管测试是否存在过程调用,因为没想测试,过程调用花费的时间
是相同的,只是上面那些代码不同。
 
全部用汇编写档次更高.
 
炒股挣了那么多,还在用P166的二手手提机,可能只能够运行Win98
我的代码用了指针后,速度没怎么提高,看来汇编还是没戏了。以后
学会了再用算了。
 
没钱,还没翻身,gcd就出利空,三几行汇编确实没啥用
 
http://www.51zhan.com 最好的网址站
 
要玩股票还是在国外比较稳当,没有谁玩得过gcd,当年陈毅进上海的时候,先也是按套路出牌,不过gcd的经济学家还是不是那些人的对手,结果gcd玩不过,钱也没了,最后给人家定为投机倒把,又把钱抢回来。所以游戏规则在人家那儿,到时想怎么变就怎么变,说不定小股民有一天变成了投机倒把分子,肆意破坏社会主义经济秩序也说不定,而前一天还说鼓厉大家炒股,全民炒股是好事。
 
to:kinneng,我是表示这么一个算法的意思,因为在循环内入栈出栈速度肯定不快。我测试了一下如下结果:
使用test 7,循环100000000次,耗时 581毫秒,代码如下:
var aa,bb,i,j: integer;
begin
aa:= 3;
bb:= 5;
j:= GetTickCount;
for i:= 0 to 100000000 do
test7(aa,bb);
showmessage(inttostr(GetTickCount-j));
showmessage(inttostr(aa)+ inttostr(bb));

然后修改为如下代码,运行时间为 190毫秒:
procedure TForm1.Button1Click(Sender: TObject);
var aa,bb,i,j: integer;
label tt;
begin
aa:= 3;
bb:= 5;
j:= GetTickCount;
asm
push ebx
mov eax,aa
mov edx,bb
mov ebx,$05F5E101
tt:mov ecx,eax
mov eax,edx
mov edx,ecx
dec ebx
jnz tt
mov aa,eax
mov bb,edx
pop ebx
end;
showmessage(inttostr(GetTickCount-j));
showmessage(inttostr(aa)+ inttostr(bb));
end;
 
另外 kinneng的test8还有改造余地,改造后时间从原先的581降低为551,效果是有,但不明显,内容如下:思路是借用ebx寄存器来代替栈操作,最后恢复ebx
procedure test8(var a, b: Integer)

asm
mov ecx,[eax]
mov [eax],ebx
mov ebx,[edx]
mov [edx],ecx
mov ecx,[eax]
mov [eax],ebx
mov ebx,ecx
end;
 
太好了,以这种办法武装起来,[8D]
 
写一个小过程,在 begin 之后暂停,只接调出CUP窗口来看汇编代码。

DELPHI是最好的编译器,就楼主提的那点汇编,DELPHI编译出的代码和
最精简的汇编没两样。因此认为没必要内嵌汇编。如果是想学汇编,
就用上面的方法。如果想优化程序,从其它方面考虑
 
在调用过程模式下的又一优化方案,速度是500毫秒,比kinneng兄的最快方案(在我机器上是580毫秒)快了大约20%不到。
呵呵,做这些测试纯粹是为了好玩,没有和谁争论高低的意思。
在调用过程模式下这个速度已达极致,即使一个只有一句mov或者完全空的过程,也是这个耗时。时间主要是花在call和ret指令上了,因为执行call之前eip值会被压栈,然后子程序的地址被加载进EIP,执行到ret时再弹出先前压栈的地址到eip等。

procedure test7;
asm
mov ecx,eax
mov eax,edx
mov edx,ecx
end;

procedure TForm1.Button1Click(Sender: TObject);
var aa,bb,i,j: integer;
label tt;
begin

aa:= 3;
bb:= 5;
j:= GetTickCount;

asm
mov eax,aa
mov edx,bb
xor ecx,ecx //这一句是多余的,但不加它,速度立马慢了10%以上,考虑可能是在生成机器码时对优化产生了影响
end;

for i:= 0 to 100000000 do
test7;

asm
mov aa,eax
mov bb,edx
end;
showmessage(inttostr(GetTickCount-j));
showmessage(inttostr(aa)+ inttostr(bb));
end;
 
to: redsky.l,编译器为了“顾全大局”,会产生一些冗余代码。有时候,手工优化一下能产生更好的效率,如我的id3735917 的代码,就比delphi产生的代码速度要快一点。当然,不是核心频繁调用的代码,无需如此费力,毕竟如果代码只执行几次,快几个时钟周期根本看不出来[:D]。而如楼主所说的每秒上亿次调用的代码,是绝对要手工优化的,一个时钟周期都不能浪费。
 
To:ufo!
你说的是对的,我是就事论事
----
比如
tmp := a;
a := b;
b := tmp;
------
就这几行代码[:D]
 
是啊,就这几行代码,经手工优化了一下,也有约5%的性能提高。
 
后退
顶部