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
runtime: software floating point for GOARM=6, 7 (not only GOARM=5) #61588
Comments
You can try using |
In triage, we think this needs to be a proposal. Since this isn't explicitly supported (and we don't have hardware for CI to test this configuration, or a test to make sure there aren't any FP instructions when setting the softfloat configuration) we'd have to make a decision to support it. |
Change https://go.dev/cl/514907 mentions this issue: |
In this comment, another user is forced to downgrade to An ARMv7 chip should execute ARMv7 instructions. Anything less leaves the CPU underutilized, and is a waste of resources. To support this proposal, I have submitted a CL that can build |
@ludi317 Have you tried the compiler flag If we really want an environment variable for the go command, my counter proposal: use an existing variable, either |
@cherrymui I did try building with the compiler flag I am not particular about the API used to specify soft float for ARM, as long as there is one. If I were to choose, I'd suggest that if |
Can you tell us what this chip is that is armv7 but without floating point? I am curious. Since you have the change prototyped, what performance differences are you seeing between |
The Aspeed AST2500 for example is a chip that supports the armv6k instruction set but does not have a floating point unit so we need to fall back to |
The chip is a BCM56160, and is found in a network switch.
I never measured the performance of our Go program when
Yes, the runtime leverages ARMv7 features. One example is that when go/src/runtime/internal/atomic/atomic_arm.s Lines 249 to 253 in 2d5ce9b
FWIW, the prototype has matured into a feature implementation that takes Finally, I came across a comment from Russ Cox indicating that back in 2011, Go supported software floating point for GOARM > 5, by setting the |
The softfloat support in Go has been reworked since then. We used to handle it in the linker (5l at the time), at instruction level, which means it would also handle (Go) assembly code (but not cgo). Now we handle it in the compiler, with |
I'd really like to see some performance numbers of the difference between |
@randall77 Please find the requested benchmarks comparing The benchmarks show many significant performance improvements, and only a few minor degradations. On the
|
So it looks like The The 64-bit atomic costs are more substantial. The arm atomics already do a runtime check, but they just use the |
|
@randall77 I thought the performance deltas in the channel-backed Based on that finding, I wrote more benchmarks to compare the performance of synchronization primitives between the two builds. Please find the results below. The
|
I suspect that the channel differences are all due to the synchronization primitives that channels use, for which we know there is already a sizable performance difference. |
Change https://go.dev/cl/525637 mentions this issue: |
Is there any additional information needed to move this proposal to "Active" status? To summarize,
|
It sounds like https://go.dev/cl/525637 is the right thing to try first, since it is not a visible API change and does not require a proposal at all. @ludi317 can you please rerun your GOARM=5 benchmarks with Keith's CL patched in? |
@rsc Please find the requested benchmarks comparing
|
This proposal has been added to the active column of the proposals project |
I came across this comment from @minux about GOARM:
I drew a table to help clarify my understanding of the relationship between a target's ARM architecture version and FPU status, and the right GOARM value to use to generate its binary. (Could be wrong; please correct any errors.) It shows what kind of instructions each GOARM value emits. The ARM architecture version {5, 6, 7} and FPU status {No FPU, VFPv1, VFPv3} are separate properties, on separate axes, as the comment says.
Many ARM targets are located on the main diagonal. Off-diagonal targets fall back to a GOARM that underutilizes their hardware. Arrows point in the direction of the fallback. For example, an ARMv7 device with no FPU drops down to a binary with ARMv5 instructions. (Dashes represent invalid combinations of architecture versions and FPUs; VFPv3 is not implemented on ARM architectures v5 and v6.) This proposal aims to avoid the 2 fallback cases in the
I wanted to frame this problem in the larger context of all fallbacks, to help guide the selection of a new set of GOARM options. For example, one advantage of the proposed softfloat / hardfloat naming scheme is that it is expressive enough to select |
Make the choice of using these instructions dynamic (triggered by cpu feature detection) rather than static (trigered by GOARM setting). if GOARM>=7, we know we have them. For GOARM=5/6, dynamically dispatch based on auxv information. Update #17082 Update #61588 Change-Id: I8a50481d942f62cf36348998a99225d0d242f8af Reviewed-on: https://go-review.googlesource.com/c/go/+/525637 TryBot-Result: Gopher Robot <gobot@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Run-TryBot: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
Thanks for the numbers showing that 7,softfloat is still better than 5 with checks. |
Have all remaining concerns about this proposal been addressed? GOARM changes to have the form When compiled with GOARM=7,softfloat, code will assume ARMv7 non-FP instructions like atomics but will use software floating point. |
Looks good, looking forward to create some real-world benchmarks as this feature might greatly boost performance due to being finally able to use the v6 and v7 ISA on non-FP chips 🎉 |
Based on the discussion above, this proposal seems like a likely accept. GOARM changes to have the form When compiled with GOARM=7,softfloat, code will assume ARMv7 non-FP instructions like atomics but will use software floating point. |
I assume |
To quote Ludi from earlier:
So I'd say
So there should not be a difference of attrs supported for each number imo. |
I think it's fine to support 5,hardfloat and easier to support it than to reject it. Maybe people on chips with broken atomics will want it. |
I updated my CL to support |
It is not too late yet. The freeze is Nov 21. |
No change in consensus, so accepted. 🎉 GOARM changes to have the form When compiled with GOARM=7,softfloat, code will assume ARMv7 non-FP instructions like atomics but will use software floating point. |
This change introduces new options to set the floating point mode on ARM targets. The GOARM version number can optionally be followed by ',hardfloat' or ',softfloat' to select whether to use hardware instructions or software emulation for floating point computations, respectively. For example, GOARM=7,softfloat. Previously, software floating point support was limited to GOARM=5. With these options, software floating point is now extended to all ARM versions, including GOARM=6 and 7. This change also extends hardware floating point to GOARM=5. GOARM=5 defaults to softfloat and GOARM=6 and 7 default to hardfloat. For #61588 Change-Id: I23dc86fbd0733b262004a2ed001e1032cf371e94 Reviewed-on: https://go-review.googlesource.com/c/go/+/514907 Run-TryBot: Michael Knyszek <mknyszek@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@google.com> Auto-Submit: Michael Knyszek <mknyszek@google.com>
The CL has been merged, I guess this can be marked as resolved then? |
I want to run a go binary on an ARMv7 target that doesn't have a hardware floating point unit (FPU). (The ARMv7 specification does not require a hardware FPU; it is optional.) Currently, the only way to use software floating point on ARM targets is to set
GOARM=5
, regardless of the actual ARM version of the target, whether 5, 6, or 7. If the decision of using software or hardware floating point were decoupled from the ARM version, then there would be no need to fall back to the ARMv5 instruction set on ARMv7 chips lacking a hardware FPU.I request a new go environment variable (perhaps
GOARMFP=soft
orhard
) that could be used alongsideGOARCH=arm
and eitherGOARM=6
orGOARM=7
to specify software ("soft") or hardware ("hard") floating point.GOARM=5
would always imply software floating point.Because this addresses an immediate business need, I have developed a working prototype for
GOARM=7
with software floating point, and could make contributions toward this new setting.The text was updated successfully, but these errors were encountered: