3 ms·
Is the "broken" approach something from the Intel-designed x86 or the AMD-designed AMD64? And is aarch64 just following what the PC world did? Seems like it.
by OldHand2018 5y ago
Is the "broken" approach something from the Intel-designed x86 or the AMD-designed AMD64? And is aarch64 just following what the PC world did? Seems like it.
Too bad PowerPC fell by the wayside.
- adrian_b 5y agoNothing was really broken, the problem was just that the 3 CPU architectures, POWER, Intel/AMD and 64-bit ARM include in their instruction sets slightly different FMA instructions, so porting a program between them requires care. The fused multiply-add instructions (FMA) have been used for the first time in 1990, in the first IBM POWER CPUs. Some years later FMA instructions have been included in many other CPUs from various vendors, the main exceptions being the Intel/AMD CPUs (where the first CPU with FMA was AMD Bulldozer in 2011, 21 years later than POWER) and the ARM CPUs, which also added FMA quite late, but before the introduction of the 64-bit variant. The problem is that both Intel and ARM have chosen to define FMA instructions that differ between themselves and also from POWER, in the position of the negation signs. With real numbers of unlimited precision, that would not have mattered, because the negation is commutative with the multiplication and distributive over addition. However with floating-point numbers these mathematical properties do not hold exactly, which is what the developers of the Dolphin emulator have discovered now. This is a general rule for any floating-point computation, that changing a formula using associativity/distributivity/commutativity is not guaranteed to produce the same results. Sometimes the differences are too small to matter, but in this case they made a game unplayable in the emulator, so they had to emulate the exact formula used in the original game, without trying to reduce the execution time by reducing the number of emulated instructions (emulating the original formula requires 2 instructions, while they initially optimized the code to use a single instruction but that computed a formula with the negation sign moved in another place).
- esrauch 5y agoThey mention precision bit then actually gave the example that if all inputs were exactly 0 that it gave differing results of +0 vs -0. Presumably the game checked the sign of the result and hit an error recovery codepath if it was negative. That's not really something that unlimited precision would avoid, but also not something that "real" arithmetic suffers from since real arithmetic doesn't have -0 and +0 as distinguishable concepts.
- adrian_b 5y agoYou are right that for that place in the game this probably exposed a bug in the original game. Normally testing the sign of a floating-point number that is the result of a multiplication or division should always be preceded by a test for zero, unless you intentionally want to take different paths for zeros with different signs.
- MontagFTB 5y agoBased on the article it sounds like the main difference comes down to calculations resulting in +0 or -0. As long as the architecture is self-consistent, it wouldn’t be a problem. Once that floating point value is sent to another architecture, things could go bad. I suppose sending FP values over the wire and used for dsync detection doesn’t happen often?