让我们再次看一下生成的代码。 方便地突出显示跳跃。然后你会看到这个...-prof perfasm
directInc:
╭│ 0x00007fa0a82a50ff: jmp 0x00007fa0a82a5116
11.39% 16.90% ││ ↗ 0x00007fa0a82a5101: inc %edx ;*iinc
││ │ ; - org.openjdk.LoopInc::directInc@46 (line 18)
12.52% 23.11% ││ │↗↗ 0x00007fa0a82a5103: mov %r10,0xe8(%r11) ;*invokevirtual putLong
││ │││ ; - java.util.concurrent.ThreadLocalRandom::nextSeed@27 (line 241)
12.00% 8.14% ││ │││ 0x00007fa0a82a510a: inc %r8d ;*iinc
││ │││ ; - org.openjdk.LoopInc::directInc@46 (line 18)
0.03% 0.03% ││ │││ 0x00007fa0a82a510d: cmp $0x3e8,%r8d
│╰ │││ 0x00007fa0a82a5114: jge 0x00007fa0a82a50c7 ;*aload_0
│ │││ ; - org.openjdk.LoopInc::directInc@11 (line 19)
0.80% 0.91% ↘ │││ 0x00007fa0a82a5116: mov 0xf0(%r11),%r10d ;*invokevirtual getInt
│││ ; - java.util.concurrent.ThreadLocalRandom::current@9 (line 222)
4.28% 1.23% │││ 0x00007fa0a82a511d: test %r10d,%r10d
╭│││ 0x00007fa0a82a5120: je 0x00007fa0a82a517b ;*ifne
││││ ; - java.util.concurrent.ThreadLocalRandom::current@12 (line 222)
2.11% 0.01% ││││ 0x00007fa0a82a5122: movabs $0x9e3779b97f4a7c15,%r10
0.01% 0.07% ││││ 0x00007fa0a82a512c: add 0xe8(%r11),%r10 ;*ladd
││││ ; - java.util.concurrent.ThreadLocalRandom::nextSeed@24 (line 242)
7.73% 1.89% ││││ 0x00007fa0a82a5133: mov %r10,%r9
1.21% 1.84% ││││ 0x00007fa0a82a5136: shr $0x21,%r9
1.90% 0.03% ││││ 0x00007fa0a82a513a: xor %r10,%r9
2.02% 0.03% ││││ 0x00007fa0a82a513d: movabs $0xff51afd7ed558ccd,%rcx
0.94% 1.82% ││││ 0x00007fa0a82a5147: imul %rcx,%r9 ;*lmul
││││ ; - java.util.concurrent.ThreadLocalRandom::mix32@9 (line 182)
7.01% 2.40% ││││ 0x00007fa0a82a514b: mov %r9,%rcx
││││ 0x00007fa0a82a514e: shr $0x21,%rcx
1.89% 0.70% ││││ 0x00007fa0a82a5152: xor %r9,%rcx
3.11% 2.55% ││││ 0x00007fa0a82a5155: movabs $0xc4ceb9fe1a85ec53,%r9
0.99% 1.50% ││││ 0x00007fa0a82a515f: imul %r9,%rcx
7.66% 2.89% ││││ 0x00007fa0a82a5163: shr $0x20,%rcx
3.70% 1.97% ││││ 0x00007fa0a82a5167: mov %ecx,%r9d
0.11% ││││ 0x00007fa0a82a516a: and $0x1,%r9d ;*iand
││││ ; - java.util.concurrent.ThreadLocalRandom::nextInt@34 (line 356)
3.76% 11.13% ││││ 0x00007fa0a82a516e: cmp $0x1,%r9d
│╰││ 0x00007fa0a82a5172: je 0x00007fa0a82a5101
10.48% 16.62% │ ││ 0x00007fa0a82a5174: test %r9d,%r9d
│ ╰│ 0x00007fa0a82a5177: je 0x00007fa0a82a5103 ;*lookupswitch
│ │ ; - org.openjdk.LoopInc::directInc@15 (line 19)
│ ╰ 0x00007fa0a82a5179: jmp 0x00007fa0a82a5103 ;*aload_0
│ ; - org.openjdk.LoopInc::directInc@11 (line 19)
↘ 0x00007fa0a82a517b: mov $0xffffff5d,%esi
间接因素:
0.01% 0.01% ↗ 0x00007f65588d8260: mov %edx,%r9d
0.01% │ 0x00007f65588d8263: nopw 0x0(%rax,%rax,1)
11.99% 11.38% │ 0x00007f65588d826c: data16 data16 xchg %ax,%ax ;*iconst_0
│ ; - org.openjdk.LoopInc::indirectInc@11 (line 34)
│ 0x00007f65588d8270: mov 0xf0(%r8),%r10d ;*invokevirtual getInt
│ ; - java.util.concurrent.ThreadLocalRandom::current@9 (line 222)
│ 0x00007f65588d8277: test %r10d,%r10d
│ 0x00007f65588d827a: je 0x00007f65588d8331 ;*ifne
│ ; - java.util.concurrent.ThreadLocalRandom::current@12 (line 222)
0.01% │ 0x00007f65588d8280: movabs $0x9e3779b97f4a7c15,%r10
11.80% 11.49% │ 0x00007f65588d828a: add 0xe8(%r8),%r10 ;*ladd
│ ; - java.util.concurrent.ThreadLocalRandom::nextSeed@24 (line 242)
0.01% 0.01% │ 0x00007f65588d8291: mov %r10,0xe8(%r8) ;*invokevirtual putLong
│ ; - java.util.concurrent.ThreadLocalRandom::nextSeed@27 (line 241)
│ 0x00007f65588d8298: mov %r9d,%edx
0.01% 0.01% │ 0x00007f65588d829b: inc %edx
11.12% 12.40% │ 0x00007f65588d829d: mov %r10,%rcx
0.01% │ 0x00007f65588d82a0: shr $0x21,%rcx
0.03% │ 0x00007f65588d82a4: xor %r10,%rcx
0.06% 0.03% │ 0x00007f65588d82a7: movabs $0xff51afd7ed558ccd,%r10
12.38% 13.94% │ 0x00007f65588d82b1: imul %r10,%rcx ;*lmul
│ ; - java.util.concurrent.ThreadLocalRandom::mix32@9 (line 182)
0.03% 0.01% │ 0x00007f65588d82b5: mov %rcx,%r10
│ 0x00007f65588d82b8: shr $0x21,%r10
0.03% │ 0x00007f65588d82bc: xor %rcx,%r10
11.43% 12.62% │ 0x00007f65588d82bf: movabs $0xc4ceb9fe1a85ec53,%rcx
0.01% │ 0x00007f65588d82c9: imul %rcx,%r10
0.34% 0.30% │ 0x00007f65588d82cd: shr $0x20,%r10
0.85% 0.76% │ 0x00007f65588d82d1: mov %r10d,%r10d
11.81% 11.51% │ 0x00007f65588d82d4: and $0x1,%r10d
2.16% 1.78% │ 0x00007f65588d82d8: cmp $0x1,%r10d
3.45% 3.00% │ 0x00007f65588d82dc: cmovne %r9d,%edx <----- HERE IT IS
17.55% 15.86% │ 0x00007f65588d82e0: inc %r11d ;*iinc
│ ; - org.openjdk.LoopInc::indirectInc@56 (line 33)
│ 0x00007f65588d82e3: cmp $0x3e8,%r11d
╰ 0x00007f65588d82ea: jl 0x00007f65588d8260 ;*if_icmpge
; - org.openjdk.LoopInc::indirectInc@8 (line 33)
请注意,而不是 - 这就是为什么我们有更多“可预测”的分支。HotSpot 分析分支,并在分支配置文件分支非常平坦时发出条件移动。换句话说,通过为条件移动的额外延迟支付一点费用来规避非常可能的分支错误预测。但是,在这种情况下,switch 是特殊的:它有两个以上的备选项(0、1 和“nothing”)。这就是为什么,我推测,增量没有被折叠成cmov。(一般来说,HotSpot本来可以将零存储到“默认”中,但它吹了它,哦,好吧)cmovne
jmp
result
result