My library runs substantially faster on x86 when compiled with the avx2
, bmi1
, bmi2
instruction sets, but even today not all hardware supports those. I think ideally the build would check whether the hardware supports these instruction sets and compile with them if so. How can I best make this happen?
I’m imagining a my-repo/build.rs
or my-repo/.cargo/config.toml
with logic like
fn main() {
let can_run_avx2 = ???;
if can_run_avx2 {
println!("cargo:rustc-cfg=feature="avx2"");
println!("cargo:rustc-env=RUSTFLAGS=-C target-feature=+avx2");
}
...
}
A non-solution:
Putting something like
[target.'cfg(target_arch = "x86_64")']
rustflags = ["-C", "target-feature=+bmi1,+bmi2,+avx2"]
into my-repo/.cargo/config.toml
would not solve my problem.
I’ve seen that, compilers will happily build unsupported instruction sets when asked, but abort at runtime because they encounter an invalid instruction they cannot actually run.
Another thing I’m worried about
It would be nice if users have a way to override this behavior, in case their compiling hardware is different from their running hardware. I could just check a custom environment variable, but it would be nicer if some top-level Cargo configuration could somehow override my settings (in contrast to the usual hierarchy).