Closed hhoffstaette closed 3 months ago
I don't think mvnd directly "asks" for CPU features, this sounds more like GraalVM issue IMHO (that produces native binary out from Java source), really unsure.
I remember having seen a similar issue in one of my pet projects. Adding -march=compatibility
to the build flags fixed it. See native-image
build options for reference.
As a workaround, one can export the env variableMVND_CLIENT=jvm
to bypass the native client.
It seems like GraalVM defaults to x86-64-v3
, which (playing devil's advocate here), seems reasonable to me (According to Wikipedia this covers CPUs released in the last 10 years, starting with Intel Haswell).
SandyBridge (released ~2011) falls right outside that range...
If one really wants to cater to CPUs that old, I would suggest -march=x86-64-v2
, since I suspect compatibility
will drop us right back to the x86_64
baseline from 2003...
Tried several -march
options on Fedora 40 with
openjdk version "22.0.1" 2024-04-16
OpenJDK Runtime Environment GraalVM CE 22.0.1+8.1 (build 22.0.1+8-jvmci-b01)
OpenJDK 64-Bit Server VM GraalVM CE 22.0.1+8.1 (build 22.0.1+8-jvmci-b01, mixed mode, sharing)
https://gist.github.com/cstamas/2d5d3cb45d60bdaf72730a1620d3f1c5
Tool used https://github.com/pkgw/elfx86exts/releases/tag/elfx86exts%400.6.2
Tried several
-march
options on Fedora 40 with
That doesn't look right..neither compatibility nor v1/v2 should use e.g. AVX2 or AVX512. But thanks for taking a look.
To reproduce, use mvnd-1.x branch and I had these changes (yes, I also enabled FFM, so it may affected it):
diff --git a/client/pom.xml b/client/pom.xml
index ba943a5a..687ace27 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -223,11 +223,12 @@
<skip>false</skip>
<mainClass>org.mvndaemon.mvnd.client.DefaultClient</mainClass>
<imageName>mvnd</imageName>
- <buildArgs>--no-server
- --no-fallback
- --allow-incomplete-classpath
+ <buildArgs>--no-fallback
+ -H:+UnlockExperimentalVMOptions
${graalvm-native-static-opt}
${graalvm-native-glibc-opt}
+ -march=native
+ -H:+ForeignAPISupport
-H:IncludeResources=org/mvndaemon/mvnd/.*
-H:IncludeResources=mvnd-bash-completion.bash
-H:-ParseRuntimeOptions
Then mvn clean package -P native -f client/
and just did change march
between:
Also, FTR my CPU is i7-13700
.
Same issue on more or less modern MacBook Pro M1 with mvnd 1.0.0
installed with sdkman.
➜ ~ sdk use mvnd 1.0.0
Using mvnd version 1.0.0 in this shell.
➜ ~ mvnd -v
The current machine does not support all of the following CPU features that are required by the image: [CX8, CMOV, FXSR, MMX, SSE, SSE2, SSE3, SSSE3, SSE4_1, SSE4_2, POPCNT, LZCNT, AVX, AVX2, BMI1, BMI2, FMA].
Please rebuild the executable with an appropriate setting of the -march option.%
Woks fine with previously available version 1.0-m8-m40
.
➜ ~ sdk use mvnd 1.0-m8-m40
Using mvnd version 1.0-m8-m40 in this shell.
➜ ~ mvnd -v
Unable to find the root directory. Create a .mvn directory in the root directory or add the root="true" attribute on the root project's model to identify it.
Apache Maven Daemon (mvnd) 1.0-m8 darwin-amd64 native client (0f4bdb6df5e74453d8d558d292789da4e66a7933)
Machine spec:
➜ ~ system_profiler SPSoftwareDataType SPHardwareDataType
...
Hardware Overview:
Model Name: MacBook Pro
Model Identifier: MacBookPro18,2
Chip: Apple M1 Max
Total Number of Cores: 10 (8 performance and 2 efficiency)
Memory: 64 GB
@asamolov Why does sdkman install the x86_64 variant on arm64 hardware? Sounds a bit strange to run mvnd through Rosetta 2... It seems Rosetta implements a very "low" x86_64 compatibility level...
(which suggest this is not the same issue at all)
For me this is what GraalVM 22 lists
$ native-image -march=list
On AMD64, the following machine types are available:
'compatibility'
CPU features: all of 'x86-64'
'haswell'
CPU features: all of 'x86-64' + SSE3 + SSSE3 + SSE4_1 + SSE4_2 + POPCNT + LZCNT + AVX + AVX2 + AES + CLMUL + BMI1 + BMI2 + FMA + F16C
'native'
CPU features: CX8 + CMOV + FXSR + MMX + AMD_3DNOW_PREFETCH + SSE + SSE2 + SSE3 + SSSE3 + SSE4_1 + SSE4_2 + POPCNT + LZCNT + TSC + TSCINV_BIT + AVX + AVX2 + AES + ERMS + CLMUL + BMI1 + BMI2 + ADX + SHA + FMA + VZEROUPPER + FLUSH + FLUSHOPT + CLWB + SERIALIZE + RDTSCP + RDPID + FSRM + F16C + PKU + OSPKE + CET_IBT + CET_SS
'skylake'
CPU features: all of 'haswell' + AMD_3DNOW_PREFETCH + ADX + FLUSHOPT
'skylake-avx512'
CPU features: all of 'skylake' + AVX512F + AVX512DQ + AVX512CD + AVX512BW + AVX512VL + CLWB + PKU
'x86-64'
CPU features: CX8 + CMOV + FXSR + MMX + SSE + SSE2
'x86-64-v1'
CPU features: all of 'x86-64'
'x86-64-v2'
CPU features: all of 'x86-64-v1' + SSE3 + SSSE3 + SSE4_1 + SSE4_2 + POPCNT
'x86-64-v3'
CPU features: all of 'x86-64-v2' + LZCNT + AVX + AVX2 + BMI1 + BMI2 + FMA + F16C
'x86-64-v4'
CPU features: all of 'x86-64-v3' + AVX512F + AVX512DQ + AVX512CD + AVX512BW + AVX512VL
@TobiX thanks for the hint, let me check why it loads darwin-amd64 instead of darwin-aarch64.
UPD: indeed, I had an old sdkman version that loaded darwin-amd64
on aarch64. sdk selfupdate
and re-installing mvnd solved the problem. Thanks again!
Please retest with binaries built by CI from here: https://github.com/apache/maven-mvnd/actions/runs/9597334445
I tested the binary from the CI run and it works. 🙌 x86-64-v2 would have been fine too but whatever; thank you very much! ❤️
@cstamas Have you done some performance comparisons between native and compatibility on a modern CPU?
Nope. @gnodet you?
I just fear that 99% of users have to suffer from that performance penalty for those 1% running on a very old CPU
I don’t expect much penalty really. The client is mostly sitting waiting for messages on a socket and printing them to stdout. Compared to the build, I would assume the loss will be negligible.
Red Hat, Open Source Integration
Email: @.*** Web: http://fusesource.com Blog: http://gnodet.blogspot.com/
Le jeu. 20 juin 2024 à 19:14, Konrad Windszus @.***> a écrit :
I just fear that 99% of users have to suffer from that performance penalty for those 1% running on a very old CPU
— Reply to this email directly, view it on GitHub https://github.com/apache/maven-mvnd/issues/1029#issuecomment-2181170907, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAUQNQKBOX3BAK3FSAR3KLZIMEWTAVCNFSM6AAAAABJOMSLG6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCOBRGE3TAOJQG4 . You are receiving this because you were mentioned.Message ID: @.***>
It may be better documented (PRs accepted), but it is hinted here: https://github.com/apache/maven-mvnd/blob/master/README.adoc#introduction
The mvnd
(or mvnd.exe
) is just a tiny native binary, that is "messenger" to background running daemons (that ARE Java). It is not "whole Maven" natively compiled, just this tiny binary. And all it does is passes user input to (selected) daemon and back, sends to console messages got from (selected) daemon.
Thank you very much for mvnd! I'm running the prebuilt binary just fine on my AMD Zen2 laptop, but when I tried the same on an older machine, I only got a sad message about a target architecture mismatch:
In my case the CPU (a SandyBridge box that still works perfectly fine) is missing LZCNT, AVX2, BMI1/2, FMA.
I know this is an old system, but it still works fine and in order to reach the widest audience it would IMHO be great if future releases could be built with a more conservative
-march
target. mvnd hardly benefits from BMI/FMA and probably only in a few synthetic benchmarks from AVX2, so this would not have any measurable performance impact.