2

次の 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 

基本的に、バブル ソート アルゴリズムの場合と同様に、2 つのループがあります。外側のループの ecx の値は 10 で、内側のループの値は [ecx-1] です。このルーチンを試してみたところ、正常にコンパイルおよび実行されましたが、効率的かどうかはわかりません。

4

3 に答える 3

3

アセンブリ コードを高速化するためにできることがいくつかあります。

  • のようなことはしないでくださいja label_1 ; jmp label_2jbe label_2代わりにやってください。

  • loop非常に遅い命令です。dec ebx; jnz loopstartはるかに高速です

  • ecx と esi を繰り返しプッシュ/ポップする代わりに、すべてのレジスタを使用します。と も使用ebxediます。

  • jmp-targets は適切に配置する必要があります。align 42 つのループ開始の前と開始後に使用します。jbe

Intel から CPU のマニュアルを入手してください (pdf としてダウンロードできます)。オペコードのタイミングが記載されています。おそらく他のヒントも記載されています。

于 2011-10-09T23:00:38.043 に答える
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++ でのソフトウェアの最適化

于 2011-10-09T23:21:01.870 に答える
0

この命令にフラグが必要ない場合は、「add esi,4」に置き換えます。

_continueLoop:
            lea esi,[esi+4]
于 2014-01-29T06:13:21.750 に答える