-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
rust should not assume NEON on armhf #35590
Comments
/cc @alexcrichton @fabricedesre @petevine This is seems to be coming from #30948 (comment). I guess this may have gone unnoticed so far because original porting has been done on a RPi2 with NEON. |
That's correct, strictly speaking, as originally there was just one However, if the official distribution methods start detecting the ISA correctly, it should be possible to add as many combinations as required. Personally, I don't like the potential fragmentation, so if it were up to me, I'd advise using the Oh, and I fully expect |
Only the |
That optimises for arm v6 so it wouldn't be ideal.
|
On the other hand, I might be privvy to one little tidbit why the targets might not be equivalent nowadays, but only in the case of mixed C,C++/Rust codebases, namely the It forces |
@infinity0 This is why you'd have to tweak the codegen, preferably via a wrapper script, in which case the target can be used as is. |
What we are arguing here is that rustc has two profiles for gnueabihf targets, none of which corresponds to the traditional definition of Linux ARMv7-HF ports. While above suggestions of probing the ISA, picking another target, and tweaking codegen are perfectly fine solution for specific users/machines, this doesn't work in the context of packaged binaries (which are moved across machines) and need to agree on the baseline architecture definition. In this specific case, rust should decide which profile is the canonical target for a Linux ARMv7-HF port, and align it to the agreed definition of that architecture baseline: |
The Rust ARM targets don't line up with the debian/gnu ones at all. Rust:
Debian/GNU:
I still think the best solution in this case would be for Debian armhf to use the |
Thanks for the report @lucab and @sylvestre! I believe @Amanieu correctly summarized the Rust state of affairs here, but could you confirm the Debian/GNU state of affairs? It'd be helpful to understand what exactly the targets Linux distros are expecting and how they're compiled. This was also discussed previously here I believe. cc @larsbergstrom, I think Servo wants NEON on for sure, right? |
@alexcrichton: I confirm @Amanieu's Debian summary above. Ignoring obsolete/historical ARM ports, Debian now has:
|
This was also discussed in #31800. As I understand, the only reason Rust ARM is v6 is to support original RPi. I objected this does not match the traditional definition. @alexcrichton decided to just ignore the definition, since RPi needs to be supported. See #31800 for details. |
Why not support the original RPi with an explicit armv6 triplet? |
Indeed. My proposal is: 1. Align Rust gnueabi/gnueabihf to v4/v7. 2. Keep (now misnamed) Rust armv7 for v7+neon. 3. Since RPi is weird, create new target just for RPi. |
Rust requires at least ARMv6, since previous versions of the architecture don't support atomic operations. |
GCC provides a (I think lock-based) std::atomic. Yes, that's slow, but I don't see a reason why Rust shouldn't allow something similar (not saying that you should all be working on that, but you shouldn't prevent people from doing it if they want to). |
Here is my understanding, excluding soft float targets for simplicity. Three targets would be best, v6/v7/v7+neon. Rust currently has v6/v7+neon. Debian wants v7. In short term, Debian can use v6 target without introducing a new target. Long term, adding v7 target seems preferable. Then there is matter of naming. Rust currently calls v6/v7/v7+neon as armhf/???/armv7. I think they should be called rpi/armhf/armv7 or armv6/armhf/armv7 to avoid confusion. Using armv7 for v7+neon is unfortunate, but it doesn't collide with existing names, and armv7 does mean v7+neon on iOS, so there's that. |
@alexcrichton We would certainly like some build of the rust standard libraries with Neon on by default for Servo. Without it, Servo is unbearably slow on any modern Android device, even if we turn it on for the Rust code in Servo itself. |
@larsbergstrom What is the baseline without it for comparison? The request here is to swap NEON for VFPv3-D16, not just to drop it. Moreover, Android targets fall under androideabi, which we are not touching here. For a comparison and historical view of the whole arm hardfloats story, see https://wiki.debian.org/ArmHardFloatPort/VfpComparison. |
@lucab: One of the key points of NEON, which isn't mentioned in that page is that it implies VFPv3-D32, whereas standard VFPv3 is VFPv3-D16. The difference here is that the former has 32-bit double-precision floating-point registers but the latter only has 16. Having more registers can help code generation in |
@lucab I don't have strong opinions about the ARM non-Android situation, and am happy to defer to the experts in this thread. So far as baseline goes, this was for Neon on some specific hardware and benchmarks that were pretty computationally intensive. We did see quite a bit of difference between soft/hard vp3/neon in that case, though clearly just getting to any hard float got the order-of-magnitude perf gains. TBH, ideally we would be able to self-build the standard library as part of Servo builds. For many of these embedded platforms the h/w provider would like to specify exactly the chipset, etc. that they have available, and asking Rust to provide every possible set of targets seems quite demanding to me. |
First, this issue is about ARM on Linux, not ARM on Android. My understanding is that Rust is simply matching Google's documentation for ARM on Android, which is great. Second, as far as I know Rust does not enable NEON for ARM on Android. So Servo must be doing something extra. This matches Google's documentation, see also #33414. |
@sanxiyn Without going into details, these builds were done with a full custom rust compiler rebuild + servo rebuild. |
So for the three Debian targets we've got:
It sounds like we can keep armv7 with VFPv3-D16, though, and it also wouldn't affect Servo as there it's primarily used on Android. If we make that change it means that armel will not be supported, but perhaps that's good enough for now? |
Just to put a counter-proposal on the table, another option would be to do
It sounds instead like we're trying to create targets that match the most |
That would be what the
Like those GCC I like that idea. The Rust equivalent would be slightly tweaking the specification of a built-in @alexcrichton thoughts on having a rustbuild mechanism to tweak "built-in" targets before the Thinking long term about the configurability of targets, the final state could look like this:
(*) This also means we don't have to release a binary for every single variation of a target: "this In that world, the |
I disagree with @japaric and I think Rust Linux targets should match Linux distros' definition (it's not like there are multiple definitions, all major Linux distros agree), and I think it is reasonable to add one more target to Rust Linux targets, growing the number from 2 to 3. After all, Rust Android targets match Google's definition, and Rust iOS targets match Apple's definition. |
FWIW, removing the neon requirement from the armv7 target is in agreement with the policy of making rustc/std more portable. The target that results from that policy happens to match "major" distros' definition and, in general, that policy will yield a rustc/std that works on most distributions because portability is its very own definition. With the policy of 'match "major" distro definition', we'd have to change the
Can't really comment on android or ios but I guess there's simply no other definition in those spaces? |
I'd be personally wary of having the definition of a target vary depending on how the compiler was built. I feel like we get a lot of mileage of having a common vocabulary when talking about targets. That is, It seems that we don't necessarily have a reason to not follow what distros are doing. In theory they're already quite conservative in feature selection, and we don't necessarily have to support everything under the sun (e.g. ARMv4 could be delayed until later). |
Ok, I've created #35814 which disables NEON but enables VFP3D16 on the |
ARMv4 is tricky. It's possible to get atomic support working for it, but only on Linux. You'd need to use the kernel user helpers to implement various |
I'm personally happy with having just armhf and arm64 aligned after this. Rationale:
|
One of the primary platforms for the `armv7-unknown-linux-gnueabihf` target, Linux distributions, do not enable NEON extensions by default. This PR disables that feature by defualt but enables the `d16` feature which enables VFP3D16 that distributions do enable. Closes rust-lang#35590
rustc: Don't enable NEON by default on armv7 Linux One of the primary platforms for the `armv7-unknown-linux-gnueabihf` target, Linux distributions, do not enable NEON extensions by default. This PR disables that feature by defualt but enables the `d16` feature which enables VFP3D16 that distributions do enable. Closes #35590
Reported here:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=834003
To quote Steve:
The text was updated successfully, but these errors were encountered: