53

enterとはどう違いますか

push ebp
mov  ebp, esp
sub  esp, imm

指示?性能差はありますか?もしそうなら、どちらが速いですか?なぜコンパイラは常に後者を使用するのですか?

leaveおよび と同様に

mov  esp, ebp
pop  ebp

指示。

4

4 に答える 4

51

特にの場合、パフォーマンスに違いがありenterます。最新のプロセッサでは、これは約10〜20 µopsにデコードされますが、アーキテクチャに応じて、3つの命令シーケンスは約4〜6です。詳細については、AgnerFogの指示表を参照してください。

さらに、このenter命令は通常、3つの命令シーケンスの3クロックの依存関係チェーンと比較して、非常に高いレイテンシーを持ちます。たとえば、core2では8クロックです。

さらに、3つの命令シーケンスは、もちろん周囲のコードに応じて、スケジューリングの目的でコンパイラによって分散され、命令のより並列な実行を可能にします。

于 2011-05-11T12:49:30.447 に答える
6

どちらを使用しても実際の速度の利点はありませんが、最近の CPU は、より一般的に使用されている短い単純な命令に対してより「最適化」されているため、おそらく長い方法の方が適切に実行されます (さらに、実行の飽和が可能になります)。運が良ければポート)。

(まだ使用されています。Windows dll を参照してください)の利点はLEAVE、スタック フレームを手動で破棄するよりも小さいことです。これは、スペースが限られている場合に非常に役立ちます。

Intel の取扱説明書 (正確にはボリューム2A) には、指示に関するより詳細な詳細が記載されています。

于 2011-05-11T08:31:17.790 に答える
6

80286 を設計するとき、Intel の CPU 設計者は、ディスプレイを維持するために 2 つの命令を追加することにしました。

CPU 内のマイクロコードは次のとおりです。

; ENTER Locals, LexLevel

push    bp              ;Save dynamic link.
mov     tempreg, sp     ;Save for later.
cmp     LexLevel, 0     ;Done if this is lex level zero.
je      Lex0

lp:
dec     LexLevel
jz      Done            ;Quit if at last lex level.
sub     bp, 2           ;Index into display in prev act rec
push    [bp]            ; and push each element there.
jmp     lp              ;Repeat for each entry.

Done:
push    tempreg         ;Add entry for current lex level.

Lex0:
mov     bp, tempreg     ;Ptr to current act rec.
sub     sp, Locals      ;Allocate local storage

ENTER に代わるものは次のとおりです。

; n, 0 を入力します; 486 で 14 サイクル

push    bp              ;1 cycle on the 486
sub     sp, n           ;1 cycle on the 486

; n, 1 ; 486 で 17 サイクルを入力します

push    bp              ;1 cycle on the 486
push    [bp-2]          ;4 cycles on the 486
mov     bp, sp          ;1 cycle on the 486
add     bp, 2           ;1 cycle on the 486
sub     sp, n           ;1 cycle on the 486

; n, 3 ; 486 で 23 サイクルを入力します

push    bp              ;1 cycle on the 486
push    [bp-2]          ;4 cycles on the 486
push    [bp-4]          ;4 cycles on the 486
push    [bp-6]          ;4 cycles on the 486
mov     bp, sp          ;1 cycle on the 486
add     bp, 6           ;1 cycle on the 486
sub     sp, n           ;1 cycle on the 486

Ect。長い道のりはファイルサイズを大きくする可能性がありますが、はるかに高速です。

最後のメモとして、プログラマーは実際にはディスプレイを使用しなくなりました。これは、非常に遅い回避策であり、現在は ENTER がかなり役に立たなくなっているためです。

ソース: https://courses.engr.illinois.edu/ece390/books/artofasm/CH12/CH12-3.html

于 2014-05-02T12:38:48.410 に答える
2

enterすべての CPU で使用できないほど遅く、速度を犠牲にしてコードサイズを最適化する場合を除いて、誰も使用しません。(フレーム ポインターが必要な場合、またはスタック スペースをアドレス指定するためのよりコンパクトなアドレス指定モードを許可する必要がある場合。)

leave 使用する価値があるほど十分に高速であり、GCCそれを使用します (ESP / RSP がまだ保存された EBP/RBP を指していない場合。それ以外の場合は、 を使用するだけですpop ebp)。

leave最新の Intel CPU ではわずか 3 uops (一部の AMD では 2 uop) です。( https://agner.org/optimize/https://uops.info/ )。

mov / pop は合計 2 uops のみです (「スタック エンジン」が ESP/RSP への更新を追跡する最新の x86 では)。つまりleave、別々に行うよりも uop が 1 つ増えるだけです。これを Skylake でテストし、ループ内の call/ret を、従来のフレーム ポインターを設定し、mov/popまたはを使用してスタック フレームを破棄する関数と比較しましたleaveperfcounters foruops_issued.anyは、mov/pop よりも leave を使用すると、フロントエンドの uop が 1 つ多く表示されます。(他の測定方法でスタック同期 uop がカウントされていた場合に備えて、独自のテストを実行しましたが、実際の関数コントロールでそれを使用しています。)

古い CPU が mov / pop の分割を維持することでより多くのメリットを得た可能性がある理由として考えられるのは、次のとおりです。

  • uop キャッシュのないほとんどの CPU (つまり、Sandybridge より前の Intel、Zen より前の AMD) では、マルチ uop 命令がデコードのボトルネックになる可能性があります。それらは最初の (「複雑な」) デコーダーでしかデコードできないため、その前のデコード サイクルが通常よりも少ない uops を生成したことを意味する可能性があります。

  • 一部の Windows 呼び出し規約は、ret n. (たとえばret 8、返信アドレスをポップした後に ESP/RSP += 8 を実行する場合)。retこれは、最新の x86のプレーンニアとは異なり、マルチ uop 命令です。したがって、上記の理由は 2 倍になります。そのままret 12にして、同じサイクルでデコードできませんでした。

  • これらの理由は、uop-cache エントリを構築するためのレガシー デコードにも当てはまります。

  • また、P5 Pentium は x86 の RISC に似たサブセットを好み、複雑な命令を個別の uop に分割することさえできませんでし

最近の CPU ではleaveuop キャッシュで 1 つの余分な uop を占有します。また、3 つすべてが uop キャッシュの同じ行にある必要があるため、前の行が部分的にしか埋められない可能性があります。したがって、x86 コードのサイズ大きくすると、実際には uop キャッシュへのパッキングが改善される可能性があります。かどうかは、物事がどのように並んでいるかによって異なります。

2 バイト (または 64 ビット モードでは 3 バイト) を節約することは、関数ごとに 1 つの余分な uop の価値がある場合とそうでない場合があります。

GCC は を支持leaveし、clang および MSVC はmov/を支持しますpop(clang -Oz速度を犠牲にしてもコードサイズの最適化を行っても、たとえばpush 1 / pop rax、 5-byte の代わりに (3 bytes) のようなことを行いますmov eax,1)。

ICC は mov/pop を優先しますが、-Os使用しますleavehttps://godbolt.org/z/95EnP3G1f

于 2021-05-06T19:41:36.050 に答える