5 ms·
Well before Bulldozer had taped out, AMD briefed us on the high level processor plans (our software was included in BAPCo Sysmark and we'd been a very early ado
by chaboud 4y ago
Well before Bulldozer had taped out, AMD briefed us on the high level processor plans (our software was included in BAPCo Sysmark and we'd been a very early adopter of AMD64, so we had lots of these meetings). I told them that it was a total mismatch for our workloads (audio and video production tools) and would prove to be a bad fit. They protested at first, as our inputs and outputs were fixed point formats and the doubled-up integer/logic units would allow us to thread more. That's when I spelled it out:
1. Our business logic and UI each basically operated in single threads.
2. Our intermediate audio and video processing buffers were floating point or moving in that direction in the future.
3. Wherever possible in filtering and effects, we avoided branching, relying on zero-folding in vector instructions.
I went on to explain where they'd be in trouble for game engines, document processing, and other key use-cases.
Their hardware architects slowly sank in demeanor over the course of that all-day meeting. I later heard from contacts at AMD that it was an "oh shit" moment for them. That said, having been at Sony at the time, we'd gone down the long dark road of the Cell...
Sometimes people try bold and interesting things that don't work. Bulldozer was definitely one of those, and it should have been killed (or at least diverted), like Larrabee. Nonetheless, AMD survived, and their current architectures owe some of their thinking to the hard-learned lessons of Bulldozer.
- zozbot234 4y agoMeanwhile the "efficiency cores" in the latest processors (both x86 and ARM) are basically optimal for precisely those highly threaded integer workloads. Bulldozer was just too early for its time.
- brnt 4y agoHmm, that's an interesting idea: two different kind of (integer) cores (big and small) sharing an FPU...
- chaboud 4y agoI totally agree that Bulldozer was ahead of its time. In some ways, it was a case of being too clever, trying to do things under the hood for the FPU similarly to Hyper-Threading for decoder/front-end resources (which also caused problems). Getting integrated with the underlying software (e.g., the kernel and its scheduler) in big.LITTLE was a comparative revelation. Conversely, the Cell took this too far, requiring that high level software be deeply SPE and memory-shuffling aware, almost like having a bank of DSPs in-package. The instruction-set/functional difference between the PPE and SPE made for encumbrances that likely would never have been fully solved by the toolchain (even if the toolchain had shipped ahead of the processor rather than well afterwards). Larrabee made attempts to solve the instruction set difference problem (in a very Intel way), but the topology, cache behavior, and pure core size proved to be far too limiting in real applications. In the end, Intel missed on the balance of core/execution-unit size vs. count when compared to Nvidia and ATI. GPGPU progress has definitely demonstrated the value of toolchain abstraction, though, and adherence to a given instruction set (and the architectural implications that came from that) proved to be a limiting constraint for Larrabee. The last 20-25 years in compute architecture design have seen many interesting articulations of clever ideas. Some deaths were predictable, but each of the explorations should be commended for the ways that they pushed boundaries and cleared the path for their successors.
- cpgxiii 4y agoI think you could draw somewhat different lessons from this, though: - Cell failed because it required too much work and was too incompatible with any other platform (save for DSPs). - Larrabee failed because KNC wasn't binary compatible and the toolchain was too much of a pain to work with, and KNL/KNM "failed" because they were too hard to get (although, I think "failed" is perhaps too strong here, the "lots of general-purpose cores with vector units" is exactly where Intel, AMD, and the aarch64 vendors have gone since). KNC's lack of binary compatibility is really what got things off on the wrong foot, the whole advantage it had over AMD/Nvidia GPUs was it amenability to GPU-unfriendly code, but I think the barrier of having to rebuild everything was prohibitive for many of the smaller users who would have been well-positioned to use it. - NVidia "won" in the GPGPU space because CUDA and its libraries have provided a stable-enough basis for complex applications to use, and the underlying hardware has evolved to be ever more performant and capable. - AMD "failed" in the GPGPU space because their toolchain abstraction is too weak and compatibility is poor. Unlike CUDA, there's no capable API that works on the whole range (even with OpenCL AMD's support is questionable at times, with two totally different driver stacks). I'd say the biggest lessons are: (1) compatibility with existing code is king, and (2) toolchain and hardware accessibility is critical. You can survive breaking (1) if your tools are good enough, but you can't win by breaking both of them.
- Accujack 4y agoLike the Alpha CPU.
- ahartmetz 4y ago...and Lisa Su was, at IBM, the team lead of the Cell CPU. Zen, about ten years later, was designed to be largely "performance compatible" with Intel Core. Similar cache, buffer, decode, etc sizes and characteristics to Core. Lessons learned, I guess.
- dist1ll 4y agoCould you explain what zero-folding is?
- sounds 4y agoSince OP didn't answer, it's probably multiplying terms by zero to mask them out.
- maximilianburke 4y agoYou don't need to multiply by zero; there are comparison operations which will generate a mask value which can then be used to select the appropriate value (`vsel` for altivec, `_mm_blend_ps` for sse4, or a combination of `_mm_and_ps` / `_mm_andnot_ps` / `_mm_or_ps` for ssse3 and earlier) At least on Xbox 360 / Cell, high performance number crunching code would often compute more than needed (ie: both the if-case and else-case) and then use a branchless select to pick the right result. It may seem like a waste but it was faster than the combination of branch misprediction as well as shuffling values from one register file to another to be able to do scalar comparisons.
- sounds 4y agoThen they would have said "masking" instead of "folding" Thanks for mentioning masking though, in case anyone thought we didn't already know about that. ;-)
- Const-me 4y ago> `_mm_blend_ps` for sse4 That instruction uses a mask provided at compile time; it encodes the mask as a part of the instruction. SSE 4 set has a similar one, `_mm_blendv_ps`, which does take the mask from another vector register.
- maximilianburke 4y agoGood catch! Thanks, I'll correct it. (edit: oops, can't fix it, it's been too long since I first wrote the comment)