Glibc sysdeps: dl_platform detection effectively performs “cripple AMD”
sourceware.org
sourceware.org
So it does not seem 100% certain, at least without testing, that using "haswell" on AMD would be beneficial (it depends on whether the speed-up from extra extensions offsets possible speed loss due to other Intel-specific optimization). And Intel was probably not going to do such testing.
But my guess is that using the "haswell" libraries on AMD will be beneficial, and the check will probably be loosened accordingly in the future.
Note, though, that the feature checks currently performed do not seem exhaustive, so I don't think one can simply remove the Intel check as-is. Haswell has a lot more extensions than the ones currently checked.
> the question is how many exceptions would arise, and what the speed penalty would be to fall back to the next slower implementation.
This can be done for essentially free with ifuncs.
Here's a crummy example from the GCC docs: https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.ht...
Here's a more thorough and (IMO) intelligible treatise on the subject: https://lwn.net/Articles/691932/
For Zen since 2017 (znver1): https://github.com/gcc-mirror/gcc/blob/44e419819c4076843d0c92dc6913821a016a8519/gcc/common/config/i386/i386-common.c#L1673-L1681
For Haswell (haswell): https://github.com/gcc-mirror/gcc/blob/b2903606a95ff609a65abe7ac0cbf4321ad2614d/gcc/config/i386/i386.h#L2372-L2382
If you collect all these entries and do some set operations on them, it should boil down to znver1 having a bunch of extra things compared to haswell {"SSE4A", "ABM", "PRFCHW", "MWAITX", "ADX", "RDSEED", "CLZERO", "CLFLUSHOPT", "XSAVEC", "XSAVES", "SHA"} and haswell only having a HLE (Hardware Lock Elision) extra. HLE is designed to be fully backward-compatible, so yes GCC Haswell code will work on Ryzen with no illegal instructions.With these very textual and probably super easy-to-parse bitset data, you should also be able to answer the "what previous things are missing" question as well. You should be able to see some historical divides with ssse3/sse4a and fma3/4 et al.
* * *
About the completeness of the check: trust me it is complete enough to only include all extant processors that are supersets of Haswell. POPCNT plus AVX2 narrows it down a quite lot.
It is quite complicated. The AMD and Intel microarchitectures are different enough in design that some low-level optimizations around many extensions really don't translate well between them. The differences can be big enough that you take them into account at the C++ level too, writing target-specific code.
Individual CPU vendors are in the best position to provide software optimization for specific implementations of their microarchitectures. Unfortunately, AMD invests relatively little in this and relies on the open source community to fill in these gaps whereas Intel is excellent at providing first-party software optimization support for their CPUs.
glibc is not Intel's project and is expected to have a minimum amount of neutrality in own it is maintained -- that also includes how patches are accepted or modifications are asked before they are integrated.
The dispatching is probably to implement things like memset & memcpy etc, which are easy to benchmark, and it is probable that the haswell version will at least be better than whatever is used right now with an amd zen (and even more probable for zenv2). Optimizing further can come later, if anybody wants to do it.
Therefore, I think this ticket is justified (but I also think that this is not a drama that is has not be taken care of sooner)
Sounds like a great benchmarking rabbit hole to go down though. :-)
For Excavator you have something like 2x128 adders and 2x128 multipliers, split over two cores.
For Zen 1 you have 2x128 adders and 2x128 multipliers per core.
For Zen 2 you have 2x256 adders and 2x256 multipliers per core.
And you can combine an adder and a multiplier to do FMA.
And for Intel chips you generally have 2x256 units that can do add or multiply or FMA.
There are a lot of workloads where you want very different strategies across these architectures.
There's a moral difference. It is wrong to intentionally degrade the performance of your competitors. It is not wrong to not do something that benefits others.
The patch however sneakily removes the chance that the features existing and working on the competing processors are properly detected and used.
In free software it’s clearly evil.
In large FOSS projects you have enough eyes on those patches to ensure they actually converge towards some (unbiased) optimum.
If they haven't tested on other processors, should they leave code in because it has a "chance" to work on something else? I think both sides of this question could be legitimately argued so I wouldn't jump to calling it "evil".
why ? AMD just has to do the same. I want to be able to use the CPU I buy to its maximum capability.
With an open source project like this, every contributor has a responsibility towards all users of that code. That means that if Intel makes a change, they are also responsible for AMD support. Putting a generic optimization behind a vendor detection is not acceptable in the community.
However, as others' have mentioned, this previously might not have benefited AMD, despite technically being supported, so it was likely meant well at the time of implementation. Intel is usually quite good players when it comes to open source contributions.
Bad implementations happen, people find better ways, they refactor and improve things. This holy war some people want to have between AMD and Intel is quite boring.
Why not? If I was maintainer I wouldn't accept the patch, I'd ask the authors to test on AMD as well. Intel is well funded and glibc is not their project. If they want glibc to include optimizations for their platform they can do the minimal level of effort to see if it can be enabled on AMD as well.
What happens if the implementation is slower but still works on AMD? Is Intel responsible for also performance testing and determining if/when to disable an implementation on a given chip? You're putting a lot of burden on Intel to do extensive testing and also not protecting them from criticism if a change is suboptimal for a competitor.
I think it's fine to submit a patch that's known to be good for a subset of CPUs and perhaps it should be tagged for another maintainer (e.g. AMD) to review and contribute to as well.
It did not, because no such testing was done.
I think there's a pretty low baseline of effort they can put in. I also think that if they enabled new code paths for newer instructions that turned out to be slower on AMD, very few people would claim this was Intel being evil. Most would blame AMD for selling a defective product.
At best you could ask them to flag platform specific code in such a way that others, who are better equipped, can test against other platforms.
It seems to me that the current approach is the most conservative: limit the impact to what you know best. Leave it to the experts of the other system to do whatever is needed.
In the end, the result of this feature is a performance improvement for some and status quo (no perf regression) for everybody else. It’s a net benefit with no downside in absolute terms.
In addition, it provides a free roadmap for AMD or its users on how to get the same benefit as well.
The potential backlash of enabling this for AMD as well by somebody of Intel (“active sabotage!!!”) is much larger than this tempest in a teacup where AMD is currently missing out on something.
> The potential backlash of enabling this for AMD as well by somebody of Intel (“active sabotage!!!”) is much larger than this tempest in a teacup where AMD is currently missing out on something.
I disagree.
It is, in facts, its role as a major contributor.
And they do, in fact, benchmark and fix AMD as part of its open source efforts, as they should. Case in point: https://github.com/OpenVisualCloud/SVT-VP9/pull/48 (Intel developer contributing AVX2 improvements, specifically mentioned as AMD Epyc improvements).
They can cater only to their own devices when the code only applies to those devices (e.g. the i915 graphics driver). In generic code paths, they must cater to all users. Adding optimization using generic features that have generic flags, but hiding them behind vendor detection, is borderline malicious. The developers here are well aware that there is a feature flag they should check instead.
What ? no. Do IBM engineers have responsibility towards Qualcomm engineers when they commit IBM patches under IBM-named flags to the linux kernel ? What happens if there's a new CPU company in two years that would also happen to work fine with these flags ?
Yes, in every way. However, with Qualcomm not having any PowerPC architectures, there isn't much harm that could be done. And for reference, Intel also tests AMD as they should, and even submits performance improvements for AMD as they should.
But this is quite bad: Instead of: `if (supports(generic_feature)) { do_with_generic_feature(); } else { slow_approach(); }`, they did `if (intel_haswell) { do_with_generic_feature(); } else { slow_approach(); }`.
The only time where that is acceptable from as big a contributor as Intel, is if they tested and concluded that other CPUs were actually slower using this feature.
> What happens if there's a new CPU company in two years that would also happen to work fine with these flags ?
That is exactly why the feature flags exist in this generic code! You can query what instruction sets are available on the CPU. Vendor-specific code should only be added to deal with product-specific defect.
A reasonable compromise is requiring architecture-specific contributions to at least do no harm to other vendors, and to not increase maintenance costs for core developers by duplicating code.
In this light, AMD engineers wanting to enable the haswell optimizations for their processors would be asked to share the existing code rather than copy-paste it. Intel engineers would participate in the public review to ensure AMD patches don't cause regressions for Haswell. If they have contributed testcases, they will demand that AMD patches pass them on all supported architectures before being merged.
This is pretty standard in all open source projects with multiple stakeholders.
Intel has made 171 contributions in form of commits to glibc as of master today. I doubt they can be considered an "occasional contributor".
And even then, small contributions only get to bypass the responsibility if we're dealing with small bugfixes.
What are you complaining about, exactly? The system is working as it ought to work.
if (intel)
fast();
else
slow();
with if (amd)
fast();
else
slow();
Or maybe there's a better way.I seriously doubt that.
Either way I agree with Mingye Wang's assessment, this kind of thing cannot be allowed to get into the source tree.
Hopefully AMD will increase their Linux activities with their new bigger market share and income.
memcpy and memset use SSE on some generations, but these days are best inlined by the compiler as "rep movsb/stosb".
This type of heuristic only works if you are the sole users of the server, e.g. a database server.
How about: don't buy affected CPUs if you care. The last thing people who write libraries should care about is a few selected CPUs that underperform on a generally useful feature.
Why? I’ve usually seen this get compiled to some version of “mov byte ptr, inc”.
But this subthread was about "where in glibc is SIMD used anyway?" and the answer is that in all code, potentially.
TBH the case for Intel isn’t that much different they have (Atoms mainly) post-Haswell CPUs that don’t support all of the instructions in this patch that would fail the master CPUID check and would not receive the optimizations either.
If someone wants to split it into checking 30 specific CPUID flags and then figuring out which libraries can be linked because many of them would require some or all of these instructions by all means do that...
When Zen was first released in 2017, using -march=haswell in gcc produced faster programs than using -march=znver1 or -march=bdverX.
Using AVX2 + FMA and all the other instructions introduced by Haswell & Broadwell was always the right thing to do when compiling for AMD Zen. Nothing has changed with Zen 2, except that the throughput of the AVX programs that are not limited by the memory throughput has doubled now.
It would be one thing if Intel did this while AMD had processors that worked on it.. but they didn't. And code cannot tell the future. That's why we have programmers. They're supposed to change the code when it needs to be changed.
In this case it doesn't need to, I believe. There are ways to find out at runtime which instruction sets are supported, in a vendor-agnostic way.
This is false. Zen was introduced in Q1 2017, before that patch was written and it already implemented all the useful parts of the Skylake instruction set (and also the SHA extension not implemented by Skylake). The fact that the CPU vendor should not be used when testing for CPU features was already discussed a lot, many years ago, so someone of the library maintainers should have noticed this bug and removed the inappropriate test.
About AMD not supporting yet AVX-512, that is far less annoying than the fact that Intel does not support AVX-512 yet in any of their CPUs which are actually competitive in their target market (Ice Lake is worse than Comet Lake, Cascade Lake is worse than Epyc 2).
Only Knights Landing, Knights Mill, Skylake Server, Cascade Lake, Cannon Lake and Ice Lake support AVX-512.
What is called "Skylake Server" in the Intel documents, includes products sold under various names, i.e. Xeon Scalable, Xeon W, Xeon D-2xxx and Skylake-X (HEDT).
I assume that you were thinking about Skylake X, but those processors are a very small fraction of a percent in comparison with all the processors using the Skylake microarchitecture, which were sold since 2015 until now, so one should never use "Skylake" to speak about "Skylake Server" a.k.a. "Skylake X", because this is very misleading.
> something that should not happen in any free software package.
Some people takes "free software" pretty wrong. Free software doesn't mean being fair to all hardwares. It only is fair to accepting contributions from people who want their machines to work with it. They would be individual contributors but they are mostly people from the hardware vendors.
That's being said, Linux/Free software have being supporting Intel very well because Intel itself is one of the biggest contributor. It's time for AMD to hire more software engineers to support better drivers and software ecosystem.
Features have feature flags, you shouldn't be doing comparison like "this is an Intel model X then it runs this" but it should be "this has feature X then it supports X" period
It's the same crap as the ICC compiler throwing the slower code at AMD even though it would support the features
This kind of bad code makes sites to ask me to run a modern browser just because my modern browser is not in the dev whitelist or this kind of bad code caused Microsoft not to have Windows9 because some developers where clever and instead of checking for features or check for win95 and win98 they wrote a shorter line of code and checked for "Win9".
In conclusion there are 2 possibilities:
1 the Intel dev did a mistake
2 it was intentional to limit the improvements to Intel only
you are arguing that 2 is fine, then you are fine if google, Facebooks, Microsoft also put checks in their commits and limit features only if the code runs in their OS,browser,site. This kind of obvious user hostile commits are bad and don't have a place in free software and IMO the Intel compiler should not intentionally cripple a competitor.
Also this attitude would mean that each company should now have a developer dedicated to check competitors contributions to make sure no intentional bad commits are sneak in because in your opinion is fair to intentionally do it.
In my experience some FB features (notes, maybe video) refuse to work on Firefox on *BSD. I tell it to lie about my UA and say that it's linux, everything works.