Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run-time feature detection #2

Open
gnzlbg opened this issue Nov 22, 2017 · 7 comments
Open

Run-time feature detection #2

gnzlbg opened this issue Nov 22, 2017 · 7 comments

Comments

@gnzlbg
Copy link

gnzlbg commented Nov 22, 2017

Currently the vector size and the SIMD instructions to be used are fixed at compile-time. This is a good first step.

It allows me to write an algorithm once, and by changing a compiler-flag generate different versions of this algorithm for different target architectures (with different vector sizes, SIMD instructions, etc.).

I really like to be able to do this at compile-time within the same binary as well, so that I can write:

// a generic algorithm
fn my_generic_algorithm<T: SimdVec>(x: T, y: T) {
   // generic simd operations
}

and monomorphize it for different instruction sets:

let x: VecAvx;
my_generic_algorithm(x, x); // AVX version
let y: VecSSE42;
my_generic_algorithm(y, y); // SSE42 version

That way input.simd_iter().map(my_generic_algorithm) could monomorphize my_generic_algorithm for SSE, SSE42, AVX, and AVX2, and do run-time feature detection to detect the best that a given CPU supports at run-time, and then dispatch to that one.

@nixpulvis
Copy link

Once Rust has compile time constants in types, this could get even more awesome I think.

@AdamNiederer
Copy link
Owner

I'm definitely interested in implementing this before 1.0.0, but I'd like to wait for stdsimd to mature a bit before jumping on it. I'll probably have methods for both static and dynamic dispatch to appease those who absolutely must save a branch.

@gnzlbg
Copy link
Author

gnzlbg commented Dec 20, 2017

It would be great if one could figure out a way of doing the dispatch only once when an iterator is consumed. That is, faster would need to monomorphize an iterator chain for multiple targets, and at run-time when the iterator is consumed the best branch is chosen before the outer-most loop.

@lilianmoraru
Copy link

Shouldn't the compiler also have support for this(run-time feature detection)?
Like Intel Compiler's -ax flag?
Or the different code paths just need to be created by the library and it is enough?

@gnzlbg
Copy link
Author

gnzlbg commented Dec 20, 2017

@lilianmoraru stdsimd has support for it: if cfg_feature_enabled!("avx") { ... } returns whether the CPU where the binary is running on supports avx.

@AndreKR
Copy link

AndreKR commented Apr 5, 2020

I'm genuinely curious what the use case for compile-time feature detection (as it is currently implemented?) would even be. Never in my life have I seen a project that provides different binaries depending on the CPU you want to run it on. I probably wouldn't even know which one to pick.

@jgarvin
Copy link

jgarvin commented Jul 13, 2021

@AndreKR it's the main way to not have the runtime cost of branching to pick the appropriate instruction set. A lot of (most?) software gets written internally by businesses for the same business, and they know what hardware they target so they don't need multiple binaries, or if they do it's simple like "last-gen" binary and "current-gen" binary. You pick the one closest to the actual CPU you know you'll be running on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants