Even though Java is a "write once, run anywhere" language, often a library will still want to use a native library, which is not only OS-specific but also host-specific. These libraries may be compiled with different CPU flags enabled, such as AVX2 or F16C, to utilise different CPU features. When loading a library from Java, the program has no clue which features may be supported, so must rely on the most accessible version - which is often the slowest. Using cpu_features, Java programs can detect which features the host CPU supports and load different native libraries based on this info.
Note: Version 2.0 of this library uses the (currently unstable) Java foreign function interface, and will require
Java 19 as well as the command line arguments --enable-preview --enable-native-access=ALL-UNNAMED
. The previous
version, using JNI and Java 15, is still available under io.github.aecsocket:cpu-features-jni:1.0.1
.
Platforms:
- Linux (x86)
- Windows (x86)
- MacOS (x86)
Architectures:
- AArch64
- ARM
- X86
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.aecsocket", "cpu-features-java", "VERSION")
// native libraries
runtimeOnly("io.github.aecsocket", "cpu-features-java-natives-linux-x86", "VERSION")
runtimeOnly("io.github.aecsocket", "cpu-features-java-natives-windows-x86", "VERSION")
runtimeOnly("io.github.aecsocket", "cpu-features-java-natives-macos-x86", "VERSION")
}
Usage is very similar to cpu_features. See HelloCpuFeatures.java to get a minimal implementation.
// If using the native library dependencies:
CpuFeatures.load();
// Otherwise load the libraries yourself:
// System.loadLibrary("cpu_features");
// CpuFeatures is the entry point to the application
CpuArchitecture arch = CpuFeatures.getArchitecture();
switch (arch) {
case ARM -> {
// The various -Info classes hold all CPU info
ArmInfo info = ArmInfo.get();
System.out.println(info.implementer);
}
case X86 -> {
X86Info info = X86Info.get()
System.out.println(info.vendor);
}
// ...
}
public static boolean useAVX2 = false;
public static void init() {
X86Info info = X86Info.get();
// Prefer accessing `features` directly over using an enum
useAVX2 = info.features().avx2();
// useAVX2 = X86Feature.AVX2.in(info.features());
Set<X86Feature> features = info.featureSet();
System.out.println("features: " + features);
}
On Windows, you need Ninja installed.
git clone https://github.com/aecsocket/cpu-features-java
cd cpu-features-java
git submodule update --init
./gradlew build