Richard Startin 在文章 A Quick Look at RoaringBitmap 中介绍 BitmapContainer
提到 Long.bitCount
在处理器支持的情况下,会被内联为调用指令 popcnt
实现。本文做简单记录,我们编写如下的代码:
1 | package me.tianshuang; |
使用 javac IntrinsicTest.java
将 Java 类编译为 class
文件,然后再使用 java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly me.tianshuang.IntrinsicTest
打印出该类对应的汇编代码,其中关键的 main
方法对应的汇编代码如下:
1 | Decoding compiled method 0x000000010e911b10: |
可以看出 line 8 Long.bitCount(i)
被编译为了基于 popcnt
的汇编指令实现,而未使用 Long.bitCount
对应的 Java 实现,我们再使用包含 -XX:-UsePopCountInstruction
的命令 java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:-UsePopCountInstruction me.tianshuang.IntrinsicTest
打印出汇编代码,该命令禁用了基于 popcnt
的指令内联:
1 | Decoding compiled method 0x0000000110911e10: |
可以看出 line 8 调用了 JDK 中的 Long.bitCount
进行实现,如果进行基准测试,那么使用了 popcnt
指令的版本会比 JDK Long.bitCount
的速度要快,在此不再演示,可以被内联的方法可以参考:vmSymbols.hpp。
Reference
Introduction to JVM Intrinsics | Baeldung
Bad Concurrency: Arithmetic Overflow and Intrinsics
GitHub - a10y/hsdis-macos: macOS Build artifacts for hsdis HotSpot Plugin
From Java to Assembly Down the Rabbit Hole (Charles Oliver Nutter, Red Hat)