代码优化提示:



我正在使用以下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]。我尝试过这个例程,它编译并运行成功,但我不确定它是否有效。

有几种方法可以加快汇编代码的速度:

  • 不要做类似ja label_1 ; jmp label_2的事情。只需执行jbe label_2即可。

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

  • 使用所有寄存器,而不是重复推送/弹出ecx和esi。同时使用ebxedi

  • jmp的目标应该保持一致。在两个循环开始之前和jbe 之后使用align 4

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

几个简单提示:

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编译器生成的代码更快的汇编代码是非常困难的,因为您应该考虑很多因素:数据和指令缓存的大小、对齐、管道、指令计时。你可以在这里找到一些好的文档。我特别推荐第一本书:在C++中优化软件

如果我们不需要此指令的标志,请替换"add esi,4":

_continueLoop:
            lea esi,[esi+4]

最新更新