CPUは、無操作のためにjmp
指示に最適化されていません。
CPUはループ用に最適化されています。 jmp .
は、多くのCPUでは1クロックで実行され、一部のCPUでは2クロックで実行されます。
ジャンプは、命令フェッチでバブルを作成します。よく予測される単一のジャンプは正常ですが、ジャンプ以外は何も実行するのは問題があります。私は、あなたのコア2のE6600の結果(メロム/コンローmicroarch)再現:
# jmp-test.S
.globl _start
_start:
mov $100000, %ecx
jmp_test:
.rept 10000
jmp . + 2
.endr
dec %ecx
jg jmp_test
mov $231, %eax
xor %ebx,%ebx
syscall # exit_group(0)
ビルドをしてして実行します(%で
7,886,461,952 L1-icache-loads # 2377.687 M/sec (74.95%)
7,715,854 L1-icache-load-misses # 2.326 M/sec (50.08%)
1,012,038,376 iTLB-loads # 305.119 M/sec (75.06%)
240 iTLB-load-misses # 0.00% of all iTLB cache hits (75.02%)
(番号:別の実行から
gcc -static -nostartfiles jmp-test.S
perf stat -e task-clock,cycles,instructions,branches,branch-misses ./a.out
Performance counter stats for './a.out':
3318.616490 task-clock (msec) # 0.997 CPUs utilized
7,940,389,811 cycles # 2.393 GHz (49.94%)
1,012,387,163 instructions # 0.13 insns per cycle (74.95%)
1,001,156,075 branches # 301.679 M/sec (75.06%)
151,609 branch-misses # 0.02% of all branches (75.08%)
3.329916991 seconds time elapsed
)は、カウンターがアクティブであった合計実行時間のうちどれくらいですか:perf
は、HWが一度に数えることができるものより多くのものをカウントするよう要求したときに、マルチプレクスする必要があります。
実際にはIキャッシュミスではなく、定数ジャンプによるフロントエンドのボトルネックをフェッチ/デコードするだけです。
私のSnBマシンは壊れているので、その上で数字をテストすることはできませんが、jmpあたり8サイクルの処理速度は結果に非常に近くなります(これはおそらく別のマイクロアーキテクチャのものでした)。
詳細については、http://agner.org/optimize/とx86タグwikiの他のリンクを参照してください。
[低速jmp命令](http://stackoverflow.com/questions/38811901/slow-jmp-instruction)の可能な複製。より詳細な質問には、はるかに優れた詳細な答えがあります。 –