3 ms·
Ah makes sense if you have complete control over your hardware it could make sense but with open source projects and businesses with a wide customer base it mig
by almatabata 3y ago
Ah makes sense if you have complete control over your hardware it could make sense but with open source projects and businesses with a wide customer base it might not make sense.
Compiled languages like Rust, C++ and Zig cannot detect the hardware because they have no runtime right? Could a language like Go add the simd semantics and detect the support vector size?
- dzaima 3y agoThe problem isn't detecting the width (that's trivially possible at runtime with a single instruction, though both SVE and RVV have a way to write loops such that you don't even need to). The problem is that a "Simd<i32, 4>" will always have 4 elements, but you'd need a "Simd<i32, whatever the hardware has>" type, which has significant impact on what is possible to do with such a type.
- almatabata 3y agoAh thank you for clarifying so you would have to create an abstraction layer on top of the current simd implementation like for example simd_vector(type, size). That abstraction would have to dynamically detect the hardware and dispatch it to the hardware like the project you shared (https://github.com/google/highway https://github.com/google/highway). So technically it sounds feasible but all of the languages like Zig, C++ and Rust picked a simpler approach. Is it simply a first step to a more abstract approach?
- dzaima 3y agoNot really - you don't need to dispatch anything, the idea is that the same code (and thus the same assembly/machine code) can operate on different sizes by itself. e.g. with RVV "vsetvli x0,x0,e32,m1,ta,ma; vadd.vv v0, v1, v2" on a CPU with 128-bit vectors will do 4 element additions, but on a CPU with 1024-bit vectors it'll do 32 additions. And some things you just can't really "generalize" to scalable vectors. e.g. you can store Simd<i32,4> in a struct or global variables, or initialize with, say, [3,2,1,0], but none of those things are possible with scalable vectors (globals/struct fields need a known size, and initializing with a hard-coded list of elements doesn't make much sense if you don't even know how many elements you'll need).
- Conscat 3y agoC++ comes with a runtime which, among many other things, allows you to detect the microarchitecture and featureset of the environment you're running on using `__builtin_cpu_init()` which calls a dynamically linked function `__cpu_indicator_init()`. Then using the `cpu_dispatch`, `target`, or `target_clones` attributes you can compile multiple variations of an algorithm in your program and dynamically select the one to execute. This is referred to as a "fat binary", and the feature is "multifunctions" or "multiversioned functions". Zig intends to support a similar feature but doesn't yet, at least not built into the language (you could certainly express this if you tried hard enough). I don't know about Rust, but I would be very surprised if it can't do this. edit: I think I replied to the wrong comment >.<