13

私は、パフォーマンスが重要なアプリケーションの非常に低レベルの部分に取り組んでいます。

生成されたアセンブリを調査しているときに、次の指示に気付きました。

lea eax,[edx*8+8]

メモリ参照 ([edx+4] など) を使用するときの加算は見慣れていましたが、乗算は初めて見ました。

  • これは、x86 プロセッサが lea 命令で単純な乗算を実行できるということですか?
  • この乗算は、命令の実行に必要なサイクル数に影響を与えますか?
  • 乗算は 2 の累乗に制限されていますか (これが当てはまると思います)。

前もって感謝します。

4

3 に答える 3

13

私のコメントを拡張し、残りの質問に答えるには...

はい、2 の累乗に制限されています。(具体的には 2、4、および 8) これは単なるシフトであるため、乗数は必要ありません。そのポイントは、インデックス変数とポインターからアドレスをすばやく生成することです。データ型は単純な 2、4、または 8 バイトのワードです。(ただし、他の用途にも悪用されることがよくあります。)

必要なサイクル数について: Agner Fog の表leaによると、一部のマシンでは命令が一定であり、他のマシンでは可変であるように見えます。

Sandy Bridge では、「複雑または裂け目」の場合、2 サイクルのペナルティがあります。しかし、「複雑」が何を意味するのかは述べられていません...したがって、ベンチマークを行わない限り、推測することしかできません。

于 2012-05-09T08:17:54.247 に答える
9

lea実際、これは命令に固有のものではありません。

このタイプのアドレッシングは と呼ばれScaled Addressing Modeます。乗算は、簡単なビット シフトによって実現されます。

左シフト

movたとえば、「スケーリングされたアドレス指定」も実行できます(これは同じ操作ではないことに注意してください。唯一の類似点はebx*4、アドレスの乗算を表すという事実です)。

 mov edx, [esi+4*ebx]

(ソース: http://www.cs.virginia.edu/~evans/cs216/guides/x86.html#memory )

より完全なリストについては、この Intel ドキュメントを参照してください。表 2-3 は、2、4、または 8 のスケーリングが許可されていることを示しています。他には何もありません。

レイテンシ (サイクル数): これはまったく影響を受けるべきではないと思います。シフトは接続の問題であり、3 つの可能なシフトから選択することは、1 つのマルチプレクサに相当する遅延の問題です。

于 2012-05-09T08:38:46.140 に答える
7

最後の質問を拡張するには:

乗算は 2 の累乗に制限されていますか (これが当てはまると思います)。

の結果が得られることに注意してくださいbase + scale * index。したがって、は 1、2、4、または 8 (x86 整数データ型のサイズ) である必要がありますが、および と同じレジスタを使用して、scaleいくつかの異なる定数による乗算と同等のものを取得できます。:baseindex

lea eax, [eax*4 + eax]   ; multiply by 5

これは、強度削減を行うためにコンパイラによって使用されます。たとえば、100 を乗算する場合、コンパイラ オプション (ターゲット CPU モデル、最適化オプション) によっては、次の結果が得られる場合があります。

lea    (%edx,%edx,4),%eax   ; eax = orig_edx * 5
lea    (%eax,%eax,4),%eax   ; eax = eax * 5 = orig_edx * 25
shl    $0x2,%eax            ; eax = eax * 4 = orig_edx * 100
于 2012-05-09T21:37:41.903 に答える