代码优化提示:

时间:2011-10-09 22:22:05

标签: sorting assembly masm masm32

我正在使用以下ASM例程对数组进行冒泡排序。我想知道我的代码效率低下:

.386
.model flat, c
option casemap:none


.code
            public sample
            sample PROC
            ;[ebp+0Ch]Length
            ;[ebp+08h]Array
                            push ebp
                            mov ebp, esp
                            push ecx
                            push edx
                            push esi
                            push eax
                            mov ecx,[ebp+0Ch]
                            mov esi,[ebp+08h]
                _bubbleSort:
                            push ecx
                            push esi
                            cmp ecx,1
                            je _exitLoop
                            sub ecx,01h
                            _miniLoop:
                                        push ecx
                                        mov edx,DWORD PTR [esi+4]
                                        cmp DWORD PTR [esi],edx
                                        ja _swap
                                        jmp _continueLoop
                            _swap:      
                                        lodsd
                                        mov DWORD PTR [esi-4],edx
                                        xchg DWORD PTR [esi],eax    
                                        jmp _skipIncrementESI
                            _continueLoop:
                                        add esi,4
                            _skipIncrementESI:
                                        pop ecx
                                        loop _miniLoop 
                            _exitLoop:
                            pop esi
                            pop ecx 
                            loop _bubbleSort
                            pop eax
                            pop esi
                            pop edx
                            pop ecx
                            pop ebp
                            ret 
            sample ENDP
            END 

基本上我有两个循环,像往常一样用于冒泡排序算法。外循环的ecx值为10,内循环的值为[ecx-1]。我已经尝试了例程,它编译并成功运行,但我不确定它是否有效。

3 个答案:

答案 0 :(得分:3)

您可以采取以下措施来加快汇编代码:

  • 不要执行ja label_1 ; jmp label_2之类的操作。只需改为jbe label_2

  • loop是一个非常慢的指令。 dec ebx; jnz loopstart更快

  • 使用所有寄存器而不是重复推送/弹出ecx和esi。也可以使用ebxedi

  • jmp-targets应该很好地对齐。在两个循环开始之前和align 4

  • 之后使用jbe

从英特尔获取自己的cpu手册(可以将其下载为pdf),它有操作码的时间,也许还有其他提示。

答案 1 :(得分:2)

几个简单的提示:

1)尽量减少条件跳转的次数,因为它们非常昂贵。如果可能,请展开。 2)重新排序指令以最小化由于数据依赖性而导致的停顿:

cmp DWORD PTR [esi],edx ;// takes some time to compute,
mov edx,DWORD PTR [esi+4] ; 
ja _swap ;// waits for results of cmp

3)避免使用旧的复合指令(decjnz对比loop更快且未绑定到ecx寄存器

编写比优化C编译器生成的代码更快的汇编代码是非常困难的,因为您应该考虑很多因素:数据大小和指令缓存,对齐,流水线,指令时序。你可以找到一些关于这个here的好文档。我特别推荐第一本书:用C ++优化软件

答案 2 :(得分:0)

如果我们不需要该指令的标志,则替换为“add esi,4”:

_continueLoop:
            lea esi,[esi+4]