1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
//! Some insight about simd, autovectorization, const generics and specialization gained from building this library //! //! i used a lot of experimental parts of rust. this is supposed to give some feedback on how //! usable i feel they are and where issues remain. This library is very Type Astronaut-y so this //! feedback is for the bleeding edge and will not represent the average usecase. //! //! # SIMD //! simd is a pain in the butt to deal with. This is true in general and specifically for rust. //! Luckily autovectorization is quite reliable if you try to play nicely with the compiler //! //! packed_simd has more #[doc(hidden)] than i have fingers, especially the core defining trait, //! SimdArray is private, which is annoying if you want to build a library thats generic over simd. //! //! simd is very platform dependent, so you have to choose to either just ask people to //! "-C target-cpu=native" or you need to provide a way to at runtime switch between //! implementations. //! //! rn you can't build your structs to suit your simd-needs bc compiler-bug/unfinishedness //! //! # Autovectorization //! Autovetcorization actually works quite well, at least in my usecase. the problem is //! reliability. i can't assure a loop actually gets vectorized. it is kinda similar to tail call //! optimization. a solution would be to have an attribute that forces optimization or fails the //! compile. //! //! # Const Generics //! Seem quite cool to me, but severely limited by the inability to build vectors of sizes //! calculated at compile time. once you can do that some really nice stuff becomes possible. //! //! Limitations are that there is no dedicated place to do const calculations on structs as you //! can't have associated constants on them. that will especially be annoying if const generics //! need to come from the same "place/expression" to be considered equal. a workaround is to //! have a wrapper type that does the calculations and an inner type that stores the results. //! Right now that leads to the inner struct not being buildable, but i think thats the same bug //! that also stops calculations in array sizes. //! //! i feel like there is some higher level concept unexpressed, a type whose size is known, but not //! nescesarily at compile time, kinda similar to TrustedLen. //! //! also, slightly related, its not possible to build a completely different struct with different //! fields based on generics or const generics. maybe thats a good thing though. //! //! # specialization //! really cool concept, have not had too many issues except some weird type inference bugs on //! (imo) unrelated places, but im not 100% sure those are due to specialization, could also be one //! of the other 10 nightly features. //! //! whats a bit weird is having a trait that has associated types and methods taking or returning //! that associated type, both being default. //! because when writing a default implementation you can't assume anything about the type since it //! could be overridden independently from the function. this is not clear from the error messages //! though. a solution here is to constrain the associated type by traits in the trait definition //! and only rely on trait methods. this does not work for return types though. //! //! also specialization feels suspiciously like inheritance //! //! # Generic Associated Types (GAT) //! there are multiple places in the library where i think GATs would have been usefull, mainly to //! stop combinatorial explosion of diferent vector-types and Add/Sub/Mul between them. The //! compiler would then on-demand be able to instanciate them into the code instead of me having to //! macro them. //! //! so im looking forward to them being implemented so i can play with them a bit //! //! # The Index trait //! sucks hard, cause it requires you to treturn an actual reference to something stored in the //! type, can't use it to on the fly generate a view (not 100% true as there is the fat pointer //! trick but thats not really... documented behaviour). had the Iterator trait made the same //! decision rust would be in a horrible state right now.