我使用下面的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。我已经尝试过这个例程,它编译并运行成功,但我不确定它是否有效。
发布于 2011-10-10 07:21:02
以下是几个简单的提示:
1)尽量减少条件跳转的次数,因为条件跳转的开销非常大。如果可能,请展开。2)重新排序指令,以最大限度地减少因数据依赖性而导致的停顿:
cmp DWORD PTR [esi],edx ;// takes some time to compute,
mov edx,DWORD PTR [esi+4] ;
ja _swap ;// waits for results of cmp3)避免旧的复合指令(dec,jnz对比loop更快,并且不绑定到ecx寄存器)
编写比优化C编译器生成的代码更快的汇编代码是相当困难的,因为你应该考虑很多因素:数据和指令缓存的大小、对齐、流水线、指令定时。你可以找到一些关于这个here的很好的文档。我特别推荐第一本书:在C++中优化软件
发布于 2011-10-10 07:00:38
你可以做几件事来加速你的汇编代码:
ja label_1 ; jmp label_2这样的事情。Just do instead.loop jbe label_2是一条非常慢的指令。dec ebx; jnz loopstart的速度要快得多,ebx和edi。在两个循环开始之前和jbe之后使用align 4
从英特尔为你的cpu买一本手册(你可以下载pdf),它有操作码的时序,也许它也有其他提示。
发布于 2014-01-29 14:13:22
如果不需要此指令的标志,请替换为"add esi,4“:
_continueLoop:
lea esi,[esi+4]https://stackoverflow.com/questions/7706961
复制相似问题