4 ms·
Note that the following are just my impressions from reading though the spec about a year ago. I did not do any deeper investigation beyond that and might misre
by CodesInChaos 8y ago
Note that the following are just my impressions from reading though the spec about a year ago. I did not do any deeper investigation beyond that and might misremember some details.
* IMO they were a bit too generous with using up 32-bit instruction encodings, only 3 of 28 major opcodes (blocks of instructions) are still reserved, though there is still some space for individual instructions within several of the used blocks. Using 4 major opcodes for 4 different sign variants of fused multiply-add seems particularly wasteful. (Of course there is still plenty of space in 48-bit and longer instruction spaces)
* Integer overflow handling code is quite verbose and might also result in lowered performance (at least in simple implementations). I'm unhappy that many languages choose silent wrapping over trapping on overflow out of performance concerns (e.g. Rust and C#), so efficient overflow checking is quite important to me. (Efficient overflow checking is also useful for seamlessly switching to big integers on overflow, which is my preferred approach for high level programming languages)
* Their approach to atomics is elegant but also unconventional. This might make porting existing code difficult. In particular the lack of double wide compare-and-swap looks like a pain point.
* Their approach to SIMD/vector instructions only seems a like a good approach for floating point arithmetic, but might struggle with common integer tasks. For example I'm not sure how shuffles fit into their variable length vector model.
* I don't like their choice of sign extending unsigned integers in the ABI.
- brandmeyer 8y ago> * IMO they were a bit too generous with using up 32-bit instruction encodings, only 3 of 28 major opcodes (blocks of instructions) are still reserved, though there is still some space for individual instructions within several of the used blocks. Using 4 major opcodes for 4 different sign variants of fused multiply-add seems particularly wasteful. (Of course there is still plenty of space in 48-bit and longer instruction spaces) Along the same vein, the FPU also uses three bits per instruction to provide for static rounding modes. Almost nobody even touches the rounding modes, and those that do only do so dynamically because that's what ARM, Power, and x86 give you. Its as if the designer wanted to get rid of the floating-point status and control register. The experiment failed, but the legacy cruft is still there.
- titzer 8y agoRounding modes aren't going away, so adding them to the instruction encoding is IMO cleaner, since it gets rid of ambient state that alters the semantics of instructions. It no doubt simplifies the internal implementation, since there are no implicit dependencies between every FP operation and the status register. Fewer dependencies == more parallelism.
- brandmeyer 8y agoThe trouble is that rounding modes need to be dynamically specified in order to enable debugging of suspicious floating-point programs. See William Kahan's rants about debugging tools for floating-point arithmetic for a detailed explanation of it, which I will attempt to summarize. If you have in hand several algorithms A, B, and C, and one or two of them produce results that differ significantly from the other, how do you tell which one is more likely to be in error? Kahan has a tool that helps: The method which is more sensitive to roundoff error will have its results perturbed worse by directed roundings, and is more likely to be the method in error. So, you run each of the suspect codes in three modes: Round to nearest even (the default), round to +inf and round to -inf. The code whose results don't change the least under directed roundings is more likely to be correct than the others. In practice, the difference can be pretty dramatic. This method just helps to point the arrow of suspicion, it isn't foolproof. But it is a useful debugging tool. Static rounding modes don't help for a broad class of problems without recompilation. Good luck running some slice of a Python program rounded three ways, for example. It also requires the ability to control which portion of the program is affected, since decimal -> float parsing code only works correctly in the round to nearest even mode. That's the crux of my argument: IEEE754 requires dynamic rounding, the numerical analyst needs dynamic rounding, and dynamic rounding subsumes static rounding. Given all that, burning three bits per opcode is pretty damn expensive, especially when you're cramming FMA4 into 32-bit opcodes. Its a mistake at least as bad as branch delay slots. But since its hiding in the floating-point portion of the ISA, it isn't as obviously wrong to the common programmer.