K.I.L.E.R
Senior Member   
Java games rock!
|
 |
«
Posted
2005-10-30 14:15:55 » |
|
Not double floats, just single floats(32 bit).
I've previously read that java has greater FP accuracy than C*('*' = wildmark for C, C++ and C#). This might be what I'm seeing, however I would like clarification if this indeed is the case.
My test was done using LWJGL's math class. All the test invovled was using vector3f's in order to do an orthogonal projection from one vector onto the same vector without the Y-COORD.
IE: vec(x, y, z) is projected onto vec(x, 0, z).
I've written my own vector class in C++ for my assignment, it uses floats and does the EXACT same operations as LWJGL's math class does because there really is only one method of working with vectors.
Anyway, the reason I projected (x, y, z) onto (x, 0, z) is to map the point onto a 3D sphere. The sphere's equation must satisfy the following condition: x*x + y*y + z*z = 1.
[size=16pt]NOTE:[/size] After doing all my computation and making sure the intermediate calculations do the EXACT same thing in both libraries(my own and LWJGL's) I've come up with 2 results.
C++: 1.000000. Java: 0.9999995.
So is Java more accurate or less accurate? Do I need to floor Java's result after every normalised vector operation?
|
Vorax: Is there a name for a "redneck" programmer? Jeff: Unemployed. 
|
|
|
Ask_Hjorth_Larsen
Junior Member  
Java games rock!
|
 |
«
Reply #1 - Posted
2005-10-30 15:34:28 » |
|
Excuse me, but how would a projection onto a plane help with projecting onto a sphere?
I don't quite understand what's going on.
|
|
|
|
|
Mark Thornton
|
 |
«
Reply #2 - Posted
2005-10-30 16:53:07 » |
|
What makes you think the C++ and Java results are actually different? In particular how did you print the result? If you were to print the Java result to only 6 decimal places it would very likely produce the same result as you printed from C++. Java's default conversion from float (and double) to string has the unusual property of containing sufficient digits to allow the original float value to be reconstructed exactly. In other words 1 2 3
| float x; float z = Float.parseFloat(String.valueOf(x)); boolean result = z == x; |
For any value of x, Java requires the result to be true. The default conversion of most other languages results in a standard number of decimal places or, for larger values, a fixed number of significant figures. To compare your results in C++ and Java more easily, I suggest you subtract 1 from the value and print the resulting 'error' term. Then the interesting information from the point of view of comparing accuracy will be in the first few digits. A second factor which may apply is that Java requires arithmetic on float values to be carried out with exactly float precision; netiher more nor less is permitted. Other languages may treat float just as a storage size and perform the computation to any convenient accuracy. Java's approach has the advantage that a developer won't be fooled into thinking his code works merely because his machine happens to compute (a badly conditioned expression) with unusual accuracy. So with Java we don't get code which works when run on an Intel machine where compiler chooses to use the 80 bit temporary real for internal values, and then fails to work on a PowerPC where ordinary double precision is used. It used to be common (at least for mathematicians) to have to tune numeric code very carefully for particular compiler and processor combinations. With Java we just target the Java specification and all conforming JVM should then produce exactly the same result (with some minor caveats for exponent overflow/underflow).
|
|
|
|
|
Games published by our own members! Check 'em out!
|
|
Mark Thornton
|
 |
«
Reply #3 - Posted
2005-10-30 17:04:20 » |
|
In any case why are you worrying about an apparent difference of only 5e-7 ?
|
|
|
|
|
K.I.L.E.R
Senior Member   
Java games rock!
|
 |
«
Reply #4 - Posted
2005-10-30 18:37:38 » |
|
Thanks. I initially used "print" to output the result. Strangely enough it's now giving me the right result.
I went into Eclipse's debugger to re-check everything and it is now giving me 1.0f exactly. Very strange issue I had. It's cleared up now.
The reason I'm worried about error is because when I do interpolation between quaternions and vectors and other stuff I need absolute precision. I'm actually thinking about writing a shader to do my calcs and then return the final result in order to keep maximum precision, then again video cards usually have less precision than general prupose CPUs.
|
Vorax: Is there a name for a "redneck" programmer? Jeff: Unemployed. 
|
|
|
Riven
|
 |
«
Reply #5 - Posted
2005-10-30 18:51:43 » |
|
You can make 32-bit float tetxures.
But as I mentioned in onther thread, the communication between the vRAM and RAM is so slow it's just not worth it. It only works out if you can reduce the vRAM<>RAM I/O to an absolute minimum. Say: hundreds or operations on each texel.
|
|
|
|
Spasi
|
 |
«
Reply #6 - Posted
2005-10-30 20:24:30 » |
|
But as I mentioned in onther thread, the communication between the vRAM and RAM is so slow it's just not worth it. I wanted to ask you this in that thread: Did you try using PBO? It's not a general solution of course, but certain algorithms could benefit from asynchronous readbacks.
|
|
|
|
|
Riven
|
 |
«
Reply #7 - Posted
2005-10-30 21:08:47 » |
|
Well, async alone won't help much, as you'd have to wait for the pixels anyway.
But the PBO spec says it's a DMA transfer (zero copy) which might speed things up, but I'll have to measure that.
|
|
|
|
Spasi
|
 |
«
Reply #8 - Posted
2005-10-30 22:24:25 » |
|
async alone won't help much, as you'd have to wait for the pixels anyway. My point was that, depending on the algorithm, you don't necessarily have to wait: 1. You run the shader at one frame and read the results at the next one (like occlusion query). 2. You do the double buffer trick, processing half the result while reading the other half (last example in the PBO spec).
|
|
|
|
|
Riven
|
 |
«
Reply #9 - Posted
2005-10-30 22:54:10 » |
|
The problem is the calculation takes about 1000 shorter than the I/O...
So when you take your approach it will be 2 times faster, yes, but what is two times faster than extremely slow worth?
Anyway, so much for the theory, I'll make a benchmark, that DMA thingy might give a significant boost all by itself.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
Markus_Persson
|
 |
«
Reply #10 - Posted
2005-11-02 14:05:38 » |
|
1 2 3
| float x; float z = Float.parseFloat(String.valueOf(x)); boolean result = z == x; |
For any value of x, Java requires the result to be true. Not true! If x == Float.NaN, result will be false.
|
|
|
|
Mark Thornton
|
 |
«
Reply #11 - Posted
2005-11-02 16:30:05 » |
|
Not true! If x == Float.NaN, result will be false.
Argh, because of course Float.NaN != Float.NaN The round trip through String does recover the identical value even for NaN, it is just the test which is tricky. The test should read Float.toIntBits(z) == Float.toIntBits(x)
|
|
|
|
|
Markus_Persson
|
 |
«
Reply #12 - Posted
2005-11-02 16:55:56 » |
|
Sorry for being so nitpicky.  I couldn't resist!
|
|
|
|
K.I.L.E.R
Senior Member   
Java games rock!
|
 |
«
Reply #13 - Posted
2005-11-04 04:47:59 » |
|
Why do you guys get on each other's nerves? "Argh" isn't exactly a friendly manner in which one would respond with.
PS: This is not an attempt by me to get flamed.
|
Vorax: Is there a name for a "redneck" programmer? Jeff: Unemployed. 
|
|
|
aldacron
Senior Member    Medals: 4
Java games rock!
|
 |
«
Reply #14 - Posted
2005-11-04 07:58:17 » |
|
Why do you guys get on each other's nerves? "Argh" isn't exactly a friendly manner in which one would respond with.
PS: This is not an attempt by me to get flamed.
'Argh' is not directed at anyone else, usually, when you read it on the forums. It's the equivalent of slapping your forehead in real life when you realize you've made a mistake. Or, as Homer would say, "Doh!".
|
|
|
|
|
K.I.L.E.R
Senior Member   
Java games rock!
|
 |
«
Reply #15 - Posted
2005-11-04 09:41:55 » |
|
That explains it. I thought it meant that he was sick of explaining things and implied the other person is an idiot. That's usually the case in some other forums I visit anyway. Sorry for the misinterpretation. Why do you guys get on each other's nerves? "Argh" isn't exactly a friendly manner in which one would respond with.
PS: This is not an attempt by me to get flamed.
'Argh' is not directed at anyone else, usually, when you read it on the forums. It's the equivalent of slapping your forehead in real life when you realize you've made a mistake. Or, as Homer would say, "Doh!".
|
Vorax: Is there a name for a "redneck" programmer? Jeff: Unemployed. 
|
|
|
Mark Thornton
|
 |
«
Reply #16 - Posted
2005-11-04 10:21:27 » |
|
'Argh' is not directed at anyone else, usually, when you read it on the forums. It's the equivalent of slapping your forehead in real life when you realize you've made a mistake. Or, as Homer would say, "Doh!".
Exactly right. The peculiar characteristic that NaN isn't equal to itself was something I ought to have remembered. At the time I was concentrating on the fact that the String conversion should round trip the values exactly (including the NaN case) and forgot that the equality test is tricky.
|
|
|
|
|
Markus_Persson
|
 |
«
Reply #17 - Posted
2005-11-04 10:32:18 » |
|
I noticed none of that getting-on-nervmanship you speak of. :-)
|
|
|
|
K.I.L.E.R
Senior Member   
Java games rock!
|
 |
«
Reply #18 - Posted
2005-11-04 15:24:48 » |
|
My bad. Not many forums are friendly and my interpretations are usually wrong.
|
Vorax: Is there a name for a "redneck" programmer? Jeff: Unemployed. 
|
|
|
swpalmer
|
 |
«
Reply #19 - Posted
2005-11-05 23:41:12 » |
|
My bad. Not many forums are friendly and my interpretations are usually wrong.
Yeah, K.I.L.E.R is a trouble maker. Let's get him!  (sorry couldn't resist)
|
|
|
|
Jeff
|
 |
«
Reply #20 - Posted
2005-11-13 05:28:34 » |
|
This may be helpful information. C has no defined accuracy of floating point calculations. It is totally platform dependant. Java has a very tightly defined floating point standard, which happens to be about the most accurate choices of options from the IEEE spec. This is oen of the issues we run into in trying to bring Java down to consumer devices, which often cheat on their floating point hardware. The PS2 is a great example,. to do Java correctly by the current spec would require software emulation of floating poitn on the PS2 
|
|
|
|
swpalmer
|
 |
«
Reply #21 - Posted
2005-11-14 04:59:18 » |
|
Can someone explain how "strictfp" affects this? I had thought that it was added so that floating point hardware could be more widely used when this option was left out... but apparently it isn't enough?
|
|
|
|
Jeff
|
 |
«
Reply #22 - Posted
2005-11-14 06:40:42 » |
|
strictfp opens up one, very limited exception, in order to allow the use of one very useful x86 mode ("fused multiply and add" as I recall) that was illegal by the original spec do to a loss of accuracy in the overflow. This was hurting code-generation on the x86.
It does not go as far as to allow any paltform's implementation of float. (*some* of us believe it should, or that there should be another 'platformfp' keyword added... )
|
|
|
|
Mark Thornton
|
 |
«
Reply #23 - Posted
2005-11-14 10:13:03 » |
|
strictfp does not change the accuracy requirements at all, instead not using it allows the use of an extended exponent range. So that instead of overflowing at about 1e308, much larger values can be represented. This is only permitted for the intermediate values of an expression. On Intel hardware it allows intermediate values to be kept on the FP stack which uses an 80 bit representation. With strictfp each intermediate value has to be saved to memory and then reloaded to force overflow to occur at the expected point. Note that although the FP stack has 80 bits for each entry calculations do not necessarily use the full 64 bit mantissa --- there is a mode setting which controls the accuracy required (float, double, extended).
Fused multiply and add is a separate issue usually relating to Power cpus, and this is still not permitted because it uses additional accuracy for the intermediate result.
|
|
|
|
|
swpalmer
|
 |
«
Reply #24 - Posted
2005-11-14 18:59:20 » |
|
ok so to summarize: Using strictfp roughly means that intermediate results must be rounded to the precision defined by the Java spec, without it intermediate results can use more precision than the spec allows for, right?
I'm with Jeff, there should probably be a 'fastfp' mode that just uses the precision inherent in the native instruction set. If it's good enough for C/C++ developers, why not? So long as you can get the precision that the spec originally asks for when you need to get the same answers across multiple platforms.
I'm betting there is already an RFE for this, anyone know the number?
|
|
|
|
Mark Thornton
|
 |
«
Reply #25 - Posted
2005-11-14 22:38:12 » |
|
Not quite the precision is always as specified. Without strictfp the range of the exponent can be extended for intermediate values only.
As for "fastfp" I think a complete anything goes would be bad idea --- there should still be some minimum requirements.
|
|
|
|
|
Jeff
|
 |
«
Reply #26 - Posted
2005-11-15 05:12:37 » |
|
Im on Cas's side here.
You can get to the platform's fp, whever it is, in C or even in Pascal. Thre shoudl be a way to do it from Java. If you are purosefully giving up some portability for speed IMHO thats fine as long as its clear that you knwo that that is what youa re doing.
|
|
|
|
Mark Thornton
|
 |
«
Reply #27 - Posted
2005-11-15 10:41:47 » |
|
I'm betting there is already an RFE for this, anyone know the number?
There was a JSR: http://jcp.org/en/jsr/detail?id=84Withdrawn 2002.03.01. Due to the general absence of interest in the community, the Specification lead withdrew the JSR.
|
|
|
|
|
princec
|
 |
«
Reply #28 - Posted
2005-11-15 11:10:31 » |
|
A good place to start would be a spec that resembles rather closely the spec of x86 FPU behaviour, don't you think  Cas 
|
|
|
|
swpalmer
|
 |
«
Reply #29 - Posted
2005-11-17 05:27:28 » |
|
Sure, it always makes sense to base things on broken technology 
|
|
|
|
|