About doubles and floats

hi

As I once said, I cannot post to the mailing list. So I’ll post here again.

As far as I know doulbes are way slower than floats. I haven’t run any tests personally. But that’s the reson, why Xith3D chose to use floats, but not doubles as Java3D does. That’s the reason, why LWJGL uses floats, but no doubles. That’s the reason, why jME uses floats, but no doubles. And OpenGL takes floats, so we don’t have to convert anything before passing it to OpenGL. And it would be great, if one would not need to constantly convert all values coming from JOODE when passed to Xith, which passes them to OpenGL.

On the other hand, if you say, that doubles are faster by far, then we need to rethink everything. Do you have any tests? Maybe the difference comes into account on 64 bit machines, which I would understand. I have an Athlon64 CPU, but I don’t run a 64 bit Linux. So I could run your tests in 32 bit mode and approve your results.

Marvin

Err…data type cant be slower or faster…:)- it all comes down to number of cycles needed for a 32bit or 64bit processor to process the data.

I guess for the OpenGl, the choice was made cos graphics hardware deals with floats…

And as for those other types of applications-well it should be connected to machine’s native word size(float=4 bytes and double 8 bytes).

I also can’t imagine why a simple switch to doubles can improve performance. But in theory, physics engines could reach faster the restitution state of objects with higher precision. The size of your 3D World is also a important factor because of the “floating point”…

AFAIK a pentium’s floating point engine is 80 bits. That means both floats (32bit) and doubles (64bit) are extebded before computation.
(SMID is probably different, but SUN’s current JVMs don’t use this anyway)

So the pure computation performance should be equal on both, but the size can matter: More single-sized floating-point values fit into the registers, so accessing many at once could load to additional (slow) load and save instructions, when dealing with double precision.

However, I’d recommand double precision for physics, because of the less rounding errors (and bienator’s argument considering restitution :slight_smile: )

With (OpenGL) Graphics I’d go for floats, especially for dynamic geometry/textures to reduce the BUS traffic.

Well, I don’t know, how important the conversion between the graphics- end physics engine’s values is. A physics engine can’t live without tghe use of some graphics engine. And if the graphics engine works with floats and the physics engine works with doubles, any values pushed around between them must be converted. I don’t know, how important this is, since I have no idea, how big the amount of transferred values is comapred to the amount of “internal” values.

Another point is, that in the future there might be physics hardware (already awailable) similar to a graphics card. Such a physics board is connected to through a similar API like OpenGL. So it will be the same for physics: everything must go over the BUS. In this case floats would be faster.

As my old physics teacher always said: “Precision is not very important. Having the third or fourth decimal place correct is absolutely sufficient. The precision imporvement is so minimal, if you do more precise calculations, is is absolutely not worth it.” Well, I guess, floats are at least sufficient for now, maybe even better because of the above arguments, and will be more beneficial in the future, when we all use physics hardware.

Marvin

I did some tests in Java on a Pentium 4 2.4Ghz processor two years ago to test out the speed of the four basic arithmetic operations.
Here are my results:



Floating Point vs Double Precision.
Iterations: 999,999,999
CPU: Pentium 4 (2.4GHz)

                 Dividing is significantly slower than multiplying.
                 All other operations are basically same speed with either
                 type. So we can use double type for most ops and get better
                 precision at the same speed.

                 Divide    Float    Double
                           ======== ========
                           10391 ms 16297 ms
                            9890 ms 16344 ms
                            9906 ms 16266 ms
                 Multiply  Float    Double
                           ======== ========
                            4938 ms  4922 ms
                            4781 ms  4914 ms
                            4781 ms  4766 ms
                 Add       Float    Double
                           ======== ========
                            4828 ms  4594 ms
                            4594 ms  4594ms
                            4610 ms  4609 ms
                 Subtract  Float    Double
                           ======== ========
                            4578 ms  4609 ms
                            4563 ms  4766 ms
                            4610 ms  4640 ms

Ahhh well thats good news then. JOODE does not need to change. I was worried by what DzzD was saying in

http://www.java-gaming.org/forums/index.php?topic=16296.msg130074;boardseen#new

.

JOODE does not utilize the full precision of floats, so using doubles for precision is not helptful. I thought I heard somewhere that floats were slower than doubles, but that seems not to be the case (but of course I would have benchmarked first).

Thanks everyone for insightful comments.

PeterB do you still have that benchmark code?

It does not look like these results could tell anythink, PeterB. :-
It seems only the division times give a small hint on the performance, as all other operations are done faster than the loop processing :stuck_out_tongue:
A benchmark ‘in the field’ would be needed.

Uh… have you seen the benchmark? What makes you think he is not doing a LOT of operations every iteration?

OK. I created an approximate atan function that works using only doubles. Here are the results
Client VM:-


precision = 10.0
atan(float)  is 22.451109
atan(double) is 23.886486
precision = 1.0
atan(float)  is 19.967203
atan(double) is 23.155668
precision = 0.1
atan(float)  is 45.209797
atan(double) is 53.017002
precision = 0.010000001
atan(float)  is 63.526928
atan(double) is 72.83537
precision = 0.0010
atan(float)  is 108.56205
atan(double) is 129.24625
precision = 1.00000005E-4
atan(float)  is 199.41187
atan(double) is 248.4359
precision = 1.0000001E-5
atan(float)  is 313.6351
atan(double) is 437.66364

Server VM:-



precision = 10.0
atan(float)  is 25.275627
atan(double) is 27.491901
precision = 1.0
atan(float)  is 22.598331
atan(double) is 21.808147
precision = 0.1
atan(float)  is 35.468964
atan(double) is 37.633972
precision = 0.010000001
atan(float)  is 61.88908
atan(double) is 70.5596
precision = 0.0010
atan(float)  is 99.14026
atan(double) is 113.27753
precision = 1.00000005E-4
atan(float)  is 163.93849
atan(double) is 214.60402
precision = 1.0000001E-5
atan(float)  is 255.63081
atan(double) is 362.96353

atan is a costly function in JOODE, so this is my field test. Horay for floats!