Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

In all of the code samples that I have looked at, the game loop looks something like this:

while(true)
{
   InputAndUpdate();
   Draw();

   SwapBuffers();
}

However doesn't this destroy parallelism between the CPU and the GPU? After the swap buffers call, the GPU will be sitting there idly while the CPU is handling input and updating. Then when the CPU has finished issuing draw commands, it waits until the GPU is finished rendering. Why isn't it done like this? :

while(true)
{
   Draw(); //First issue the draw commands
   InputAndUpdate(); //Update while the GPU is busy rendering

   SwapBuffers(); //Now block and wait for the GPU to finish
}
share|improve this question
    
This is something I've never considered. +1 interesting question. –  The Communist Duck May 22 '11 at 12:05
    
The first one. If doing the second you increase the input lag by a full frame, possibly more depending on how you get input in the first place and V-sync. Always make sure not to increase the input lag –  Psykocyber May 22 '11 at 14:23

2 Answers 2

up vote 5 down vote accepted

This would be true unless you have an extra back buffer to render into (double-buffering). That allows the CPU to carry on and do stuff without having to wait for the actual buffer swap to occur (which would normally be the case as you couldn't start modifying the back buffer until it had been copied to the front buffer without risk of corrupting what you just rendered). When a draw call or swap is made, the request goes into a buffer of commands that the GPU can process, allowing the CPU to get on with doing other things while the GPU runs behind. This is how modern hardware gets parallelism. I believe D3D has a limit on just how many frames you can render ahead before a "Swap" will block (you'd need multiple back buffers to achieve this - also the more you buffer up the more latency you can potentially introduce between the input method and what is appearing on screen).

The concept of a game loop like either example above is quite dated. With the introduction of multiple processing units on the CPU you could potentially be doing rendering on one thread while doing some "update" work on one or more others. You might want to look into the concept of job queues to help maximise all the CPU processing power available.

share|improve this answer

the solution you sied doesn't accualy make CPU and GPU to work parrarel, it just changes the order they are waiting for each other, since as the other answer implys draw always put it's results into a backbuffer and using swapbuffers you only change what is monitor shoing with the latest thing drawn, to take full potential of both CPU and GPU you have to call draw and update in two diffrent threads and use another second buffer for what CPU is doing (so that when CPu is generating update results in buffer 2 GPU read from Buffer 1 and when CPU is working with Buffer 1 GPu use Buffer 2 just like swap buffers GPU uses to prevent changes in frame already drawn)

share|improve this answer
    
@Gajet are you suggesting to double-buffer all game data on the cpu-side too? –  Maik Semder May 22 '11 at 18:55
    
somthing like that, but not all data, only the thing that can move. so that both GPU&CPU read from CPUbuffer[0] and each do their calculations, and save their results in memory buffer/CPUBuffer[1], and when both their works finished they start reading from CPUBuffer[1] –  Ali.S May 22 '11 at 19:12
    
This is overkill, impractical and ends up in a messy code-base since the game entity will have normal and double-buffered properties relevant to rendering. There are much easier solutions for the communication from game-thread to the render-thread, like command queues. -1 for suggesting this –  Maik Semder May 22 '11 at 19:42
    
agreed but i think it's the only way you can fully use the power of CPU and GPU simultaneously, command queues fir example won't work since every time CPU finnished a generating frame data it should give all it's data to GPU, and this means you have to wait CPU finishes working and then copy all the buffer at that time, keep in mind that nothing in the world should change while GPU is drawing the world, so if you use command queues there won't be any change in CPU and GPU waiting for each other. –  Ali.S May 22 '11 at 19:48
    
The fact that one waits for the other to finish does not mean that they don't run in parallel, they do, but the first one that finishes has to wait, since rendering and game-update must be synced. But they fully run in parallel. So the double-buffer suggestion solves a problem that is not there. –  Maik Semder May 22 '11 at 20:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.