--- Log opened Wed Jul 24 00:00:49 2013 | ||
-!- munaafghumran [~mg0950@cpc10-aztw24-2-0-cust177.aztw.cable.virginmedia.com] has joined #mageec | 07:38 | |
AWhetter | Weird bugs day #2: The result of an arithmetic expression is different on 32 bit and 64 bit, despite the operands being the same and overflow not occuring | 11:43 |
---|---|---|
AWhetter | This seems odd. The expression is of the form (ans += a * b) where all variables are floats. If I store a * b in a float before adding the float to ans, it works | 12:03 |
@simoncook | try a*b in brackets? | 12:06 |
@simoncook | it shouldnt make a difference as * has higer precedence than += but possibly worth a try | 12:07 |
AWhetter | Nope. Doesn't work | 12:08 |
@simoncook | does the difference in assembly generated hint at anything | 12:08 |
AWhetter | How do I find that out? | 12:10 |
@simoncook | adding -S to gcc will stop the compilation after generating an assembly file, or -save-temps will save all the temporaries including the assembly file and finish compilation, then just diff | 12:11 |
@simoncook | what types are a and b? | 12:16 |
AWhetter | floats | 12:17 |
AWhetter | I don't really know assembly well enough but I think there's something that might be significantly different. | 12:18 |
AWhetter | Would you mind taking a look? | 12:18 |
@simoncook | I can, I was just about to get lunch, so I can look in about half an hour | 12:20 |
AWhetter | ok. Maybe I'll go for lunch as well then. | 12:20 |
AWhetter | http://underrun.org/~gadget/32to64.diff | 12:20 |
AWhetter | The diff is there though whenever you get back | 12:20 |
AWhetter | Thanks :) | 12:20 |
@simoncook | can you also link the code that you built | 12:21 |
-!- amylaar_ [~joern@cust213-dsl91-135-11.idnet.net] has joined #mageec | 12:35 | |
@jeremybennett | I asked amylaar_ (Joern) to join and give the benefit of his expertise | 12:43 |
AWhetter | simoncook: yeah. I'll tar it up now | 12:47 |
AWhetter | http://underrun.org/~gadget/float_matmult.tar.gz | 12:50 |
AWhetter | The line is line 222 in matmult.c | 12:51 |
AWhetter | At the moment it has the working code but if you remove the to_add variable is fails on 32 bit | 12:52 |
AWhetter | It's the 337th loop iteration that fails. So in gdb I'm doing break 222, run, continue 337, *check variables*, continue, *check variables* and the result is incorrect | 12:54 |
@simoncook | so on an incorrect result it exists with non-zero return code, its working fine here for me in both cases | 12:59 |
@simoncook | aah wait, without you said, let me change that | 12:59 |
@simoncook | Have you run this on a non-x86 platform, does this also fail, I think this may be just errors in comparing two floats (0.000013668251%) | 13:27 |
@simoncook | Just rounding errors, ignorable IMO | 13:28 |
AWhetter | Not sure. I'll run it on one of the ARM boards now | 13:42 |
@jeremybennett | Looking at the values in your checking array, you are close to the limit of 32-bit floats - around 7 decimal digits | 13:44 |
@jeremybennett | In fact you are beyond - you are specifying 9 digits. FP calculations are tricky around the limit a = x * y followed by b +=a may not give the same result as b += x * y if the internal calculation is done to greater accuracy. | 13:47 |
AWhetter | I'll double check but it looks like it works on arm | 13:48 |
@jeremybennett | I suspect there is an option to enforce strict 32-bit IEE 745 compliance, but I could imagine that by default the internal FP calculation is more accurate, and so you may have variability in the last bit. | 13:48 |
AWhetter | Yep. It works on arm | 13:49 |
@jeremybennett | I suggest your test for correctness should be tolerant of a +/- 1-bit variation in the LSB of the mantissa. | 13:49 |
amylaar_ | there's -ffloat-store, and -mfpmath=sse . | 14:01 |
@jeremybennett | And by IEEE 745 I mean IEEE 754 (http://en.wikipedia.org/wiki/IEEE_754-1985) | 14:06 |
AWhetter | It works if I ignore the least significant bit of the mantissa | 14:25 |
AWhetter | Thanks for the help everyone | 14:25 |
@simoncook | Just to add a possible minor complication, are you ignoring that bit in a way that doesnt break regardless of endianness | 14:27 |
AWhetter | No but it's easy to make it work for both | 14:28 |
AWhetter | I have no idea if the other benchmarks are going to work on any endianness though | 14:28 |
@jeremybennett | But they ought to. I imagine we have both LE and BE devices in our collection. | 14:29 |
amylaar_ | on most hosts, the endianness of int32_t and float is the same. | 14:38 |
amylaar_ | To cover the rest, you'd have to do some complex tests - either autoconf, or something done at runtime in your program. | 14:39 |
-!- munaafghumran_ [~mg0950@cpc10-aztw24-2-0-cust177.aztw.cable.virginmedia.com] has joined #mageec | 20:11 | |
-!- munaafghumran [~mg0950@cpc10-aztw24-2-0-cust177.aztw.cable.virginmedia.com] has quit [Ping timeout: 268 seconds] | 20:14 | |
-!- munaafghumran_ [~mg0950@cpc10-aztw24-2-0-cust177.aztw.cable.virginmedia.com] has quit [Ping timeout: 268 seconds] | 21:47 | |
--- Log closed Thu Jul 25 00:00:54 2013 |
Generated by irclog2html.py 2.12.1 by Marius Gedminas - find it at mg.pov.lt!