double vs single precision graphics pipeline

Started by
7 comments, last by Yann L 14 years, 1 month ago
I'm using double precision for all my calculations on the CPU as I think I can afford it relatively well. The only place I'm having mixed feelings about using double precision (or more appropriately, about the way how to use double precision) is feeding data to the GPU. Three simple questions stem from this: Are most GPU's still natively running in single precision mode nowadays? As I'm keeping everything in double precision, should I just feed the GPU double precision data and have the driver/onboard converter (is there such a thing?) take care of the possible conversion or should I do the conversion in my own renderer? Seeing as single precision is really okay for things that don't scale that much, can one expect to see double precision becoming the native operational mode for GPU's in the near future (if it isn't such already)? The reason I'm asking these seemingly silly questions is that I'm really only using the graphics card for output - I don't consider myself a graphics programmer and I'm not very good at it. I have a pretty solid grasp of the basics, but I do not pretend to be overly knowledgeable about the innards or the inner workings of the card itself or its drivers.
Advertisement
Double-precision support is very new for GPU's. ATI added it with their 3000-series, and Nvidia added it for the GTX-200 series. I believe the ATI GPU's do double-precision at half-speed, while the GTX-280 does it at 1/8th speed (the new Fermi-based GPU's do it at half-speed). So you'd be at a pretty significant disadvantage if you utilized doubles. Also there are no DXGI formats that support double precision, so vertex and texture data would still be capped at 32 bits. The conversion to single precision could be pretty significant, depending on what you're doing. You'd be losing the ability to just memcpy data into your buffers that you send to the GPU. It would also make it difficult for you to leverage math libraries, or SIMD extensions.

I'm not sure that the situation will improve much beyond this in the near future, since single precision is fine for graphics. It's generally only a subset of GPGPU programmers that require double precision.

Forgot about this thread :). Thanks for the concise and to-the-point reply, MJP!
I am going to disagree with Matt on this one. I am using DirectX 11 for construction visualization and if you are working to the millimeter then with only 6.5 digits of precision I cannot represent anything bigger than 999999.0 millimeters (i.e. 1 kilometer) which is less than 1 mile visually with common origin. To represent a 400 km road for construction purposes means a big problem adjusting local origins which is really a very big nuisance.

Same when working with LIDAR data which easily can be many miles long based on a single origin (the initial scan path).

DirectX/XNA is NOT just for games. Unless you want to force me to move to OpenGL with its double precision support? I would rather not go this way as I have built up a lot of experience with DirectX starting with the early versions. It has become an essential part of my toolkit and I love using the new shaders (GS/CS especially). People are constantly amazed by the performance that DirectX provides. So much so that this has become my mathematics work horse.

But PLEASE, PLEASE give us a double precision GPU pathway and XNA maths library. I do not see ANY indication of an XNA math library using double precision. This is now a huge problem.
Quote:Original post by genifycom
DirectX/XNA is NOT just for games. Unless you want to force me to move to OpenGL with its double precision support? I would rather not go this way as I have built up a lot of experience with DirectX starting with the early versions. It has become an essential part of my toolkit and I love using the new shaders (GS/CS especially). People are constantly amazed by the performance that DirectX provides. So much so that this has become my mathematics work horse.

But PLEASE, PLEASE give us a double precision GPU pathway and XNA maths library. I do not see ANY indication of an XNA math library using double precision. This is now a huge problem.


I think you misunderstood me. My first point was just that if you have the choice between double and single precision, single precision is a better choice since you'll get better performance both on the CPU and the GPU. If you need double precision (as in your case), then go ahead and use it. DX11 supports it! I certainly wouldn't recommend that you switch to OpenGL. The issue is the hardware, not the API.

My second point was that I don't think Nvidia or ATI are going to be sacrificing their single precision performance for the sake of increased double precision performance. Obviously the market for non-gaming applications on the GPU is growing rapidly, but at the this particular moment in time both IHV's still depend heavily on gaming-oriented consumers buying their hardware in order to fund their R&D costs. In the future that might change, who knows. I'm not very good at predicting these things! I was just giving my overall impression of what the landscape is like at the moment.

As for XNA Math, it's pretty obvious that it's library meant for game developers. Game developers rarely have a need for double precision, so it's pretty understandable that Microsoft wouldn't include it. However it is possible to to use SSE instructions with doubles, but you'll have to do two components per vector instead of 4. There might already be a library out there that does this...it's not really my area of expertise so I'm not sure of what options are available.
you really dont need doubles for _rendering_

usually objects are stored in their local coordinates, big objects (like terrain) are cut into chucks of local coordinates, there are a lot of games dealing with fairly big dimesions like e.g. space games, where you need to see planets in large distances, big ships and tiny fighter and your zbuffer is just 24bit and look how nicely games handle that (like eve online).

You can get away with float pretty good, you just adjust the matrices relativ to the view point and it works out. I had to get that kind of rendering working with the 16bit&24bit precision that the PSP pipeline offers you and it was working for a fairly large world.
racing games like NFS have quite long tracks and GTA3 also runs with that 16bit. I know of some games that use 16bit floats on consoles to save memory for their objects in fairly big worlds and it works. Games like crysis simulate physics (so they need lot of accuracy to get it stable) in a large world, wow, daoc and other mmorpg have vast terrains that would never workout with float if you wouldn't compensate it, so they do that for sure -> it works out.

Sure, doubles would be an out-of-the-box solution till you reach their limits (e.g. flying from earth to moon and showing some screw), but it isn't as much of an headache as it seems to be once you implement that local offset. (btw. in some cases doubles also reach their limits in games, e.g. terrain would have gaps, thats why some games save positions etc as fix point values in 64bit ints, the distribution is equally across the whole world).


edit: if it is scientific and not for gaming, maybe software rendering would be suitable? (you would sacrify performance on GPU as well if you'd force doubles, like mentioned by an previous poster: 1/8th)
Quote:Original post by Krypt0n
you really dont need doubles for _rendering_

That's correct, but it comes with a few caveats.

Thing is, more than just rendering is done on the GPU nowadays. For example consider GPU based fluid dynamics. And now imagine handling situations where part of your fluid can spill into several local sectors, each with their own local reference frame. Or having very large animated objects that cross several sectors, and each part of the dynamic object must match the local precision of the sector it currently resides in.

But yeah, you can do that. We do industrial/scientific visualization. We keep the original geometric data CPU side in a 64.192 fixed point format. For rendering, we convert that on the fly into standard 32 bit floats, sectorized with local origins. Works very well, and is entirely transparent to the user.

But conditions at sector borders are sometimes ill-defined and can cause problems.
Quote:Original post by Yann L
Quote:Original post by Krypt0n
you really dont need doubles for _rendering_

That's correct, but it comes with a few caveats.

Thing is, more than just rendering is done on the GPU nowadays. For example consider GPU based fluid dynamics. And now imagine handling situations where part of your fluid can spill into several local sectors, each with their own local reference frame. Or having very large animated objects that cross several sectors, and each part of the dynamic object must match the local precision of the sector it currently resides in.

That's why I underlined "rendering".
Scientific computations need high precision for sure, even double gets sometimes to it's limit and needs complex solutions to avoid that (even game physics have stability issues when calculated with doubles).
But visualizing the results of those computations does not strictly need double.
Sure, fluids would have quite some overhead for conversion, so it would be probably smarter to render them directly. But big meshes can be statically hold in local-space float formats.

Quote:
But yeah, you can do that. We do industrial/scientific visualization. We keep the original geometric data CPU side in a 64.192 fixed point format. For rendering, we convert that on the fly into standard 32 bit floats, sectorized with local origins. Works very well, and is entirely transparent to the user.

But conditions at sector borders are sometimes ill-defined and can cause problems.

That's what I said, kinda :D


Quote:Original post by Krypt0n
That's why I underlined "rendering".

Even simple rendering can be problematic. Consider a simulation for a large scale construction site. Say you want to position a highly detailed suspension bridge onto a terrain. This bridge needs sub-millimeter precision and is over a kilometer long. So floats aren't enough.

You have two options. You can re-sectorize the bridge on the fly after each and every modification that was done on it, and you'll have to reupload the sectors that changed to the GPU for rendering. That's quite involved, but you can stay with floats that way. Or you can just upload the entire model as doubles and simply modify the matrices when someone moves a single bolt or the entire bridge around. That takes more memory and is heavier on the GPU, but it's well defined without border conditions and it saves host-GPU bandwidth.

Such scenarios must be profiled in practice.

This topic is closed to new replies.

Advertisement