おそらく、レジスタ間接アクセスの方がわずかに高速ですが、たとえば、エンコーディングが短いことは確かです (警告 — ガス構文)。
67 89 18 mov %ebx, (%eax)
67 8b 18 mov (%eax), %ebx
対。
89 1c 25 00 00 00 00 mov %ebx, some_addr
8b 1c 25 00 00 00 00 mov some_addr, %ebx
そのため、インストルメントの読み込み中、キャッシュの使用などにいくつかの影響があるため、おそらく少し高速ですが、読み取りと書き込みを伴う長い関数では、それほど重要ではないと思います...
(16 進コードのゼロは、リンカーによって埋められることになっています (これを言っただけです)。)
[更新日="2012-09-30 ~21h30 CEST":
私はいくつかのテストを実行しましたが、彼らが何を明らかにしたのか本当に疑問に思っています. 私はそれ以上調査しなかったほどです:-)
48 8D 04 25 00 00 00 00 leaq s_var,%rax
C7 00 CC BA ED FE movl $0xfeedbacc,(%rax)
ほとんどの実行で、よりも優れたパフォーマンスを発揮します
C7 04 25 00 00 00 00 CC movl $0xfeedbacc,s_var
BA ED FE
私は本当に驚いており、マラティシュツァがこれをどのように説明するのだろうと思っています. 私はすでにアイデアを持っていますが、私は喜んでいます...なんて楽しい...いいえ、これらの(例)の結果を見てください
movl to s_var
All 000000000E95F890 244709520
Avg 00000000000000E9 233
Min 00000000000000C8 200
Max 0000000000276B22 2583330
leaq s_var, movl to (reg)
All 000000000BF77C80 200768640
Avg 00000000000000BF 191
Min 00000000000000AA 170
Max 00000000001755C0 1529280
確かに、命令デコーダーはサイクルごとに最大 8 バイトを取るという彼の声明を支持するかもしれませんが、実際にデコードされたバイト数は示されていません。
leaq
/ペアではmovl
、各命令は (オペランドを含めて) 8 バイト未満であるため、各命令は 1 サイクル内でディスパッチされる可能性が高く、1 つの命令はmovl
2 つに分割されます。それでも、デコーダーが速度を落としているわけではないと確信しています。11 バイトであってもmovl
、3 番目のバイトの後に作業が行われるためです。アドレスと即時のパイプライン ストリーミングを待つ必要があります。デコードする必要はありません。
これは 64 ビット モードのコードであるため、1 バイト短いリップ相対アドレッシングでもテストしましたが、(ほぼ) 同じ結果が得られました。
注: これらの測定値は、実行される (マイクロ) アーキテクチャに大きく依存する場合があります。上記の値は、Atom N450 (一定の TSC、boot@1.6GHz、テスト実行中は 1.0GHz に固定) でテスト コードを実行した場合のものであり、x86(-64) プラットフォーム全体を代表するものではありません。
注: 測定は実行時に行われ、タスク/コンテキストの切り替えやその他の割り込みの発生など、それ以上の分析は行われません!
/アップデート]