Skip to main content
gamedev.net
🔒 Locked

A reentrant graphics API, how usefull is it really?

Started by _the_phantom_ 8 replies 1.6k views
Original Post
_the_phantom_
_the_phantom_
OK, so in another thread it was put forth that one of the things OpenGL would 'fall over on' was its lack of Multi-thread support. Now, we already had some small discussion on this in that thread, however as it was off-topic I figured I'd start a new thread and see if we can get some other peoples input on it. Note: This is purely about the graphics API, not a game engine or games in general, as Oluseyi said Multi-threaded game programming is coming, and it will be everywhere soon. Get ready., which I fully agree with and totally see the point to doing. So, anyone who starts wandering off along the lines of 'you can do multiple engine tasks at once' should be removed from the convo and shot for not paying attension, ok? So, my point of view on this is that while having a reentrant API is 'nice' in that it allows you to render from 2 or more threads at once without worrying about it, for anything beyond simple tests I submit that its not very usefull. Graphics card are inherently state based systems; you set something and its set until you change it and its a well known fact among graphics programmers that in order to get the best possible performance you need to keep your state changes to the lowest minimum, so that the graphics card doesnt have to keep flushing pipelines and generally stalling all over the place. This means that you need to perform some sort of sort to ensure that you dont set redundant states. Now, in a single drawing thread world this is easy, you set the state and you draw, happy in the knowledge that until you tell it otherwise the state wont change magically behind your back, you are happy, the graphics pipeline is happy and all is good with the world. Now, in a world were you can have two or more threads drawing at once things get a bit sticky. This is because in theory the state can change at any point between drawing calls, it might not ofcourse but you cant rely on that. So, something somewhere either needs to track the state and save it (as pointed out to me a way of doing this exists in D3D and also exists in OGL just not in one function call), a job which can be done by the graphics API or the calling application. Now, if its done via the gfx API you pay for the cost of this save/restore everytime you use it (well, unless you have a function which tell it 'this is going to be used via MT' so it sets an internal flag), however by contrast if you move it to the calling application you have to come up with locking routines etc to ensure things cant stamp over your state before you are done with it, at which point what use is a reentrant API if you have to do a load of management yourself? (not to mention the pointlessness of getting stuck in a mutex or other control block while you wait for a thread to finish up) So, lets assume the API takes the first route of the API doing the management and lets assume you can tell its going to be working in an MT system where any thread can render to it. The state tracking still has to be applied, at which point you run into the cost of state changes. Even with just two threads rendering 15 objects (with 10 in thread 1 and 5 in thread 2) there is a chance of at most 10 state changes (I'm assuming the API is smart and tracks state chances sanely, so if the state hasnt change it wont try to change it back again), which depending on the states could be nowt more than a slight blip to a horrible waste of time. Ofcourse, you could wrap both drawiing routines in a mutex or other MT sync system but then you lose your advantage of being reentrant again. With all this taken into consideration I fail to see how being reentrant is an advantage, the cost of state switches and the nightmare if must be for the driver writers to handle it just make it look like more of a problem than its worth. thoughts? comments? agree or am I completely off base here?
leiavoia
leiavoia
For rendering, i see no benefit at all to multithreading. Basically it would like letting a painter paint a canvas, while suddenly switching the canvas out for another one at any time at random. The drawing process needs to run from start to finish in order to render a scene correctly before it can move onto the next frame. You can't be drawing parts of one frame and parts of another at the same time. It doesn't seem to make any sense to do that. Multithreading, even if it worked right, would only slow down the process because of the thread switching and checking to make sure the state was constantly correct.

Now it does make sense to have multiple threads for AI, updating, and drawing, but not for drawing alone. That's how i see it.
evolutional
evolutional
I'm not au fais with hardcore graphics techniques, so take this with a pinch of salt...

In SQL server, you effectivley have a system that can only exist in one definitive 'state'. The records are either there, or they aren't. RDMS tend to utilise a paradigm called 'ACID' (Atomicity, Consistency, Isolation, Durability) to handle transactions within the database. Transactional processing essentially allows multiple processes to use the database at a time, but anything that wishes to commit a change must either aquire an exclusive lock on the data or insert their updates in a queue that *must* complete or it is rolled back (to maintain the atomic nature of the transaction). Likewise, anything that needs to be read must be done with an exclusive lock (to guarantee the accuracy) or without a lock, which is faster and doesn't lock the system, but there are no guarantees it's results are reflective of what's actually there.

So, with my naive view of the process, I can see a similar system being of potential use in graphics programming. Instead of having to set individual states, I can see a transactional model being beneficial. The application thread would then wrap state changes in an atomic transaction (consisting of one or more state change) which is either committed (the states change) or is rolled back (no states are changed).

Whether this technique is applicable to graphics APIs or not is entirely debateable.
Toni Petrina
Toni Petrina
Quote:
Original post by leiavoia
Now it does make sense to have multiple threads for AI, updating, and drawing, but not for drawing alone. That's how i see it.


That is true. How about SLI solution? Can we make each card draw on different backbuffer? This could give shadow mapping or HDR a giant leap. Just think about it : two shadow maps in virtually same time.

Also works for all image space based techniques such as occlusion culling, ambient occlusion, etc.
So... Muira Yoshimoto sliced off his head, walked 8 miles, and defeated a Mongolian horde... by beating them with his head?

Documentation? "We are writing games, we don't have to document anything".
mattnewport
mattnewport
When Longhorn and the WGF comes along drivers will have to deal with multiple processes trying to use the graphics card at the same time anyway so it's probably not going to be much extra work for them to support multiple threads in a single process. Future graphics hardware targeted at WGF 2.0 is going to have hardware support for context switching on the GPU and sharing the GPU efficiently across multiple threads / processes.

That said, I'm not convinced it is a great benefit to have the API allow drawing commands from more than one thread. It seems like it would make the game code more rather than less complex in most cases and the state management issues are likely to be painful. Behind the scenes both OpenGL and Direct3D eventually end up building command buffers which are submitted to the GPU and executed serially and I'm not sure how useful it is to try and present a multithreaded interface to the programmer built on top of that.
kburkhart84
kburkhart84
I agree with what most have said. Why draw from multiple threads. There is only one screen and (usually) one video card. The state changes already are enough to manage without having multiple threads. Maybe for AI or loading levels something like that in the background, I see a use for multithreading, but not for rendering.


ParadigmShift
ParadigmShift
The only possible multithreading benefit I can see is if you wanted to separate your texture and geometry upload logic from your state change/render call logic. This would be more of a driver thing, though. Actually having multiple threads rendering at once makes no sense unless you have context switching on the card.

Tom
"E-mail is for geeks and pedophiles." -Cruel Intentions
markr
markr
As far as I'm aware, current GPUs / drivers can't benefit from multiple threads trying to render at once. At least not on consumer-grade hardware.

Potentially if we have some kind of multiple independent GPUs system like could exist on various consoles now or in future consoles, several GPUs can each be driven by one host thread with almost no interference (I am not a console developer and know little about consoles)

Early arcade machines frequently employed multiple CPUs and graphics chips to operate in parallel, with some kind of display multiplexing hardware for the output - this enabled them to do faster graphics than would otherwise have been possible on the hardware of the day.

Perhaps ultimately this will happen on desktops, but don't hold your breath :)

Mark

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.