8 ms·
The point is to put Haswell-optimized code in the "haswell" subdirectory. However, compiling code with -march=haswell (implying -mtune=haswell) does a lot of ot
by AnssiH 7y ago
The point is to put Haswell-optimized code in the "haswell" subdirectory. However, compiling code with -march=haswell (implying -mtune=haswell) does a lot of other platform/manufacturer-specific optimizations as well (not just usage of the various extensions), like favoring instructions X that perform slightly better over other instructions Y, even if instructions X would be significantly slower on AMD processors.
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.
- iforgotpassword 7y agoI'm not sure it is even worth it to distinguish by CPU model. My hunch is that the optimizations the compiler does for a specific model are vastly overshadowed by the gains of having certain extensions available at all. So glibc should only distinguish by avx512, sse4.2, etc. usually a CPU that has a newer extension available also has all of the older ones, the question is how many exceptions would arise, and what the speed penalty would be to fall back to the next slower implementation.
- jandrewrogers 7y agoThe implementations of extensions on different CPU microarchitectures can vary quite a bit from the same vendor. And performance of those extensions can vary by an order of magnitude between CPU vendors, sometimes because vendors will initially add CPU extensions as microcode if they did not design the extension themselves. AMD has microcoded many Intel extensions in some of their architectures for binary compatibility but without performance benefits, and many of their native implementations behave differently in material ways for optimization. The existence of the feature does not imply you should use it for highly optimized code, it may be slower than software versions of the same thing, or that you should use the feature in the same way to optimize code. 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.
- temac 7y agoAlthough you probably overestimate a bit the impact of uarch diff between haswell and zen, there is some truth in theory in what you said. In practice, zen is quite close to Skylake in terms of general uarch principles and main figures, and zenv2 even more so (or even better). IIRC for ZenV1 AVX2 should yield no gain compared to AVX, though. 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)
- iforgotpassword 7y agoThanks for the insight, last time I remember writing assembly for speed was probably the early sse days. Sounds like a great benchmarking rabbit hole to go down though. :-)
- loeg 7y agoPutting aside most of your earlier comment, > 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.html#index-_005f_005fbuiltin_005fcpu_005finit-1 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/ https://lwn.net/Articles/691932/
- arthur2e5 7y agoThe FMV (4.8) and clone (6.0) features are intended to be easier-to-use wrappers around ifunc. FMV-4.8 (C++) generates the ifunc dispatching code for the programmer, and FMV-6.0 (C/C++) moves on to do the code duplication for the programmer too. It is added with the assumption that GCC's optimization / vectorization magic is good enough to gain significant performance gains by just changing -march options on the exact same piece of code.
- arthur2e5 7y agoA good way for the lazy person (me) to find out what processors have what instructions is simply dig in the GCC source code and see what their enormous tables have to say. 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.
- Dylan16807 7y agoI don't know, the vector units vary a huge amount. Let's say you have an AMD chip with AVX2. 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.