VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
楼主: littlekevin

还能优化吗?

[复制链接]
 楼主| 发表于 2009-2-9 18:52:03 | 显示全部楼层
原帖由 VBProFan 于 2009-2-9 15:31 发表


没关系,反正loop是两个版本代码的公共部分。我原来还在循环体内加了个 cmp ebx, 0ffffffffh 呢,也同样得出 sub 比 dec 快的结论。


用什么东西把循环代码写好?  这样测更加不准

-------- ...


mov ecx,1000000(这个数还可以更大些...)
dectest:
dec ecx
dec ecx
dec ecx
dec ecx
dec ecx
dec ecx
dec ecx
dec ecx
dec ecx
dec ecx
jnz dectest
;------------------
mov ecx,1000000
subtest:
sub ecx,1
sub ecx,1
sub ecx,1
sub ecx,1
sub ecx,1
sub ecx,1
sub ecx,1
sub ecx,1
sub ecx,1
sub ecx,1
jnz subtest
回复 支持 反对

使用道具 举报

发表于 2009-2-9 19:15:11 | 显示全部楼层
是的, AMD 的cpu的确有过人的地方,虽然主频不高,但执行效率却远远强于 intel,这点从我以前写vb代码的经验上就感觉到了,特别是循环,感觉那效率要比intel高出N个数量级的效率,我还写过这方面的讨论,在这论坛上发过,但无人理解,被我删了

把我知道的和想起来的再说些,inc 这个指令也是影响标志位的,但有资料说,这个指令是属于基本指令,他具有不可打断的性质,在执行其他指令操作时,都可能因线程切换等其他原因,被系统时钟中断打断,而inc 是无法打断的. 另据资料... 对寄存器的操作,尽量使用 eax 来完成,据说 eax 被特殊优化了,效率要比其他寄存器更高,对于代码的优化,其实不应该只从速度方面考虑,有的速度确实很快,但可能导致指令码长度大量增加,有的很慢,但可能只用两3行就实现了需要的效果.不应该只考虑效率问题,在16时代,指令长度也是个很重要的问题. mov eax,-1 和 or eax,-1 相比.... 理论上来说可能mov可能更快点,因为对标志位的影响也是需要耗时的.

对于 inc 快还是 add 快,我坚持 inc ,原因和楼上发现 amd 的问题,差不多,不同的cpu可能有不同的结果,单纯的测试毫无意义.

以 intel 来说,每个系列的cpu都有他的特殊性,表现在对某些指令执行速度上

对于跳转指令,我认为应该用 ja,jg,jl,je,jo 等单条件跳转指令,向 jne,jng,jle,jnl.... 多重条件指令,我认为单条件指令可能更快.

这些东西我不会去测试,对我来说,我认为基本意义不大,我只简直自己的观点,按自己的认为的可能的情况做了.

我也有个代码,谁有兴趣.一起讨论下,帮我改改
cVal proc cstring
        ; invoke cVal,ctext("123ad546hsg") , eax = 123546
        ; ErrorResult = OF is 1 = eax = 0
        invoke lstrlen,cstring      '这个谁帮忙写个 rep cmps ...懒的弄了,这东西我居然写了10个小时
        mov ecx,eax
        cmp ecx,13
        jl ready
        mov ecx,12

ready:        lea edi,cstring
        mov edi,[edi]
        dec edi
        xor esi,esi
        mov eax,1
        xor edx,edx
@@:
        mov dl,[edi+ecx]
        cmp edx,030h
        jl Nextlop
        cmp  edx,039h
        jg Nextlop
        sub edx,030h
        cmp eax,1
        jne mul1
        mov eax,0ah
        mov ebx,edx
        jmp putdat
mul1:
        mov ebx,eax
        mul edx
        xchg ebx,eax
        mov edx,10
        mul edx
        jo ErrOF
putdat:       
        add esi,ebx
       
Nextlop:sub ecx,1
        jne @B
        mov eax,esi
        ret
ErrOF:  xor eax,eax
        ret
cVal endp

一个让我写了整整一夜,的 val 函数.......而且很烂我也承认......-_-""" i..... 别问为什么,有好的建议请告诉我
我的想法是,减少乘法的次数,而且最好支持无符号乘法...

[ 本帖最后由 PctGL 于 2009-2-9 19:50 编辑 ]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-2-9 20:29:31 | 显示全部楼层
cVal proc
;pointer to string - ebx
;ret:eax

invoke lstrlen,ebx ;我也懒的写了..

mov ecx,eax ;ecx=strlen
add ebx,ecx ;ebx=字符串最后的0字节
not ecx     ;ecx= -strlen-1
            ;not a = (neg a) - 1 !
sub eax,eax ;eax=0

        cmp ecx,13
        jl ready
        mov ecx,12 这一段什么意思?


@@1:
inc ecx     ;so first time,ecx=-strlen.
jz @@finish ;if ecx=0 then finish
movzx dl,byte ptr [ebx+ecx]   ;第一次,ecx=-strlen,ebx+ecx=字符串开头
                              ;每一次循环都ecx+1,所以ebx+ecx就往后移一个字节
sub edx,030h   ;优化了一点
jc @@1
cmp edx,09d
ja @@1

test eax,eax   ;eax=0 then no need to *10
jz @@nomul     

;eax=eax*10=eax*(8+2)
add eax,eax   ;eax=eax*2
mov edi,eax   ;edi=eax*2
add eax,eax   ;eax=eax*4
add eax,eax   ;eax=eax*8
add eax,edi   ;eax+edi=eax*8+eax*2=eax*10

@@nomul:
add eax,edx  ;加上当前的数字
jmp @@1

@@finish: ret

cVal endp


刚刚用记事本写的,没拿去试到底对不对..不对请改正

[ 本帖最后由 littlekevin 于 2009-2-9 20:33 编辑 ]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-2-9 20:31:42 | 显示全部楼层
“据说eax被特殊优化了,效率比其他寄存器要高”
只是机器码短1字节而已
xchg eax,reg32    1 bytes
xchg reg32,reg32  2 bytes
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-2-9 20:37:00 | 显示全部楼层
我问的不是mov和or,而是
mov eax,-1
mov dword ptr [ebx],eax 和

mov dword ptr [ebx],-1

这2个的效率
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-2-9 20:38:27 | 显示全部楼层
对了,说起代码大小,我有一个20字节的排序..

;
; bubble sort
;
; input:
;   edi = pointer to array
;   ecx = number of indexes
;
; output:
;   edi = pointer to sorted array
;
; destroys:
;   eax, edx
;   eflags
;

outerloop:
        lea     ebx,[edi+ecx*4]
        mov     eax,[edi]
cmploop:
        sub     ebx,4
        cmp     eax,[ebx]
        jle     notyet
        xchg    eax,[ebx]
notyet:
        cmp     ebx,edi
        jnz     cmploop
        stods
        loop    outerloop

by Andrew Howe from Core Designs
回复 支持 反对

使用道具 举报

发表于 2009-2-9 21:08:17 | 显示全部楼层
cmp ecx,13
jl ready
....
我的一个算法,还受人bs了... 我认为dd的最大表示长度是10位,就是10亿位,所以只该取10个数字(那个代码有点问题,应该是cmp 11,mov 10),因为算法是根据结果累加出来的,每个数字在不同位都代表了不同的数,所以只能取10位,再说的话结果就不对了,因为of 了

mov eax,-1 和 mov mem,-1 比较速度? 你说呢
对 eax 的优化,你怎么知道仅仅是减少了一个字节码? 而没有效率的优化?

add 是好东西... 我对算法基本达到了无视的地步... 写代码也写不出来什么更好的代码,对算法几乎一窍不通,想想,.. 几个连加达到了mul的目的...   为什么我总不能把数学和计算机联系上....
回复 支持 反对

使用道具 举报

发表于 2009-2-9 21:19:54 | 显示全部楼层
原帖由 PctGL 于 2009-2-9 19:15 发表
对于 inc 快还是 add 快,我坚持 inc ,原因和楼上发现 amd 的问题,差不多,不同的cpu可能有不同的结果,单纯的测试毫无意义.

如果对10000台P4的机器的测试效果都是add快,对10000台8086的机器的测试效果都是inc快,那么还是有意义的。虽然不完全归纳法不准确,但建立在量子力学基础上的现代电子技术理论是可靠的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-2-9 21:23:39 | 显示全部楼层
没bs你...是我看不懂..

不是让你比较mov eax,-1 和 mov mem,-1....
是mov eax,-1 / mov mem,eax 和 mov mem,-1...
回复 支持 反对

使用道具 举报

发表于 2009-2-9 22:50:01 | 显示全部楼层
>是mov eax,-1 / mov mem,eax 和 mov mem,-1...

486- 的时代没有 mov reg/mem , imm
>386 之后才出的

看intel的指令手册上,操作 imm 的速度和操作寄存器的速度相当,
但看操作器, 操作寄存器和操作内存速度能一样吗

[ 本帖最后由 PctGL 于 2009-2-9 22:52 编辑 ]
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2023-3-22 05:23

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表