-march=native versus x86-64-v3 for heterogeneous x86-64 deployment targets
0 reputation · 20 Jan 2020, 01:42 UTC
0 reputation · 20 Jan 2020, 01:42 UTC
The goal is to compile x86-64 binaries that exploit AVX2, BMI2, and FMA while remaining safe to execute across a deployment fleet whose exact CPU mix is not fully known or controlled. The build environment may differ from production, and cloud or virtualized targets can expose a subset of host features.
Two documented approaches create a trade-off. Using -march=native detects the build host's ISA extensions and can yield peak performance on that machine, but it risks SIGILL on older Intel, AMD, or virtualized CPUs that lack those instructions. Using -march=x86-64-v3 provides a portable microarchitecture level that enables the same post-2013 extensions without host-specific detection, though it requires GCC 11 or newer and assumes every target supports that baseline.
Neither flag resolves floating-point auto-vectorization semantics: -O3 with either level may vectorize reductions and alter rounding unless -ffast-math is explicitly supplied.
When the deployment fleet includes pre-Haswell Intel, pre-Excavator AMD, and cloud VMs with masked CPU features, is the performance gain from -march=native worth the risk of illegal-instruction faults compared with the x86-64-v3 baseline? If the build pipeline runs in containers or CI where the hypervisor's visible feature set may not match production hardware, should the portable level be preferred even when the build host reports newer extensions? Does the unresolved rounding behavior under -O3 auto-vectorization change the choice between these two -march levels, or does it require a separate decision about -ffast-math?
A thoughtful contribution can make all the difference. Be the first to share one.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.