Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSE 380 – Computer Game Programming Render Threading Portal, by Valve,

Similar presentations


Presentation on theme: "CSE 380 – Computer Game Programming Render Threading Portal, by Valve,"— Presentation transcript:

1 CSE 380 – Computer Game Programming Render Threading Portal, by Valve, http://orange.half-life2.com/portal.htmlhttp://orange.half-life2.com/portal.html

2 What is multi-tasking? Doing many things simultaneously On a computer, Operating Systems run multiple programs simultaneously When you’re working, how many different applications do you have open at one time? Games use threads to do multiple things simultaneously –Why? better utilization better framerates/performance

3 Threads Individual programs appear to do multitasking Each task is called a thread Programs that can run more than one thread at once are called multithreaded –a program is broken up into a number of threads of control –all threads share the same address space (data). –threads communicate with each other via the shared objects –operations in threads are scheduled by a thread scheduler (typically OS)

4 Why do we get a performance advantage? Imagine you wanted to make a CAR Approach 1: –Step 1: make 4 tires –Step2: when done with Step 1, Make a windshield –… –Step 1,000,000,000: Assemble Car 1. Make 4 Tires 2. Make a windshield 1,000,000,000. Assemble Car …

5 Why do we get a performance advantage? Imagine you wanted to make a CAR Approach 2: –Step 1: Simultaneously have different workers/suppliers make the windshield, engine, tires, etc. –Step 2: Assemble car as parts are available 1a. Make 4 Tires 1b. Make a windshield 2. Assemble Car …

6 How do you check for broken eggs? You buy a carton of eggs You don’t want any broken Option 1: –Take out and check them one at a time –Poor utilization. Why? because 11 eggs are idle while we check one of them Option 2: –Open carton and look at top –Flip carton upside down –Open carton and look at bottom –High utilization. Why? eggs are never waiting for other eggs that have been removed and are being examined

7 Utilization You don’t want your program to be idle when there’s work to be done. Like: –while our game loop is sleeping –while we’re retrieving user input –while expensive rendering is going on For multi-core: –while one core is doing something the others shouldn’t be idle

8 Typical Thread Tasks Rendering –separate thread only performs rendering –expensive operation Networking and I/O –threads may wait for messages –they check buffer continuously for immediate response Physics –do pathfinding on one CPU and physics on another

9 Using a Render Thread One approach: –Thread 1: all game updates (AI, Collisions, etc.) –Thread 2: all rendering, and only rendering Strategy: –Each frame: Thread 1 builds a RenderList Simultaneously Thread 2 renders the RenderList Thread 1 had built the previous frame –Note: this means we’ll need 2 RenderLists

10 2 RenderLists RenderList *renderList1, *renderList2; Each frame: Thread 1 If time to process data: Set time to process data to false Process data and build render list 1 Swap render lists 1 and 2 Set time to render to true Thread 2 If time to render: Set time to render to false Render render list 2 Set time to process data to true

11 Race Conditions Threads are independent pieces of control operating on shared data. If we’re not careful: –thread 2 could overwrite thread 1’s changes data corruption –thread 2 could try to use thread 1’s changes prematurely –or vice versa One thread corrupting shared data for the other threads is called a race condition Common to Consumer – Producer relationships –one thread is the producer (thread 1) –one thread is the consumer (thread 2)

12 How do we prevent race conditions? Mutexes. What’s that? –A mutex puts a lock on a piece of data –1 st thread reserves a piece of data –2 nd thread cannot use it until the 1 st thread is done with it Windows Mutexes: –WaitForSingleObject – requests a reservation http://msdn2.microsoft.com/en-us/library/ms687032(VS.85).aspx –ReleaseMutex – releases a reservation http://msdn2.microsoft.com/en-us/library/ms685066(VS.85).aspx What should we be locking? –anything used by both threads RenderLists, TextureManagers, text to render, etc.

13 Using Mutexes (type HANDLE) RenderList*renderList; HANDLErenderListMutex; … // WHEN WE WANT TO USE renderList WaitForSingleObject(renderListMutex, INFINITE);...// USE renderList ReleaseMutex(renderListMutex); // NOW THE OTHER THREAD CAN USE IT

14 Complication: Deadlock What’s that? –Thread 1 has a lock on object A –Thread 1 is waiting for object B –Thread 2 has a lock on object B –Thread 2 is waiting for object A Can bring a program to a halt How do we resolve it? –prevent it from happening through a well thought-out mutex/lock strategy

15 Platform dependency & threads One drawback of threads Thread libraries are typically system dependent For example: –C++’s CreateThread function creates threads C/C++ runtime (CRT) will not get properly initialized on Windows

16 Windows Thread Management _beginthreadex –starts a thread –you provide the method to run in that thread unsigned __stdcall MyMethod ( void* pArguments ) typically would have a loop tied to game loop timing –http://msdn2.microsoft.com/en-us/library/kdzttdcb(VS.80).aspxhttp://msdn2.microsoft.com/en-us/library/kdzttdcb(VS.80).aspx _endthreadex –stops a thread –http://msdn2.microsoft.com/en-us/library/hw264s73(VS.80).aspxhttp://msdn2.microsoft.com/en-us/library/hw264s73(VS.80).aspx

17 So we’ll need a Windows Thread class GameRenderThread – could be a virtual class with just method headers WindowsGameRenderThread – could be a Windows implementation of GameRenderThread

18 GameRenderThread.h class GameRenderThread { public: virtual void kill()=0; virtual void runFromMainThread(Game *game)=0; virtual void start(Game *game)=0; };

19 WindowsGameRenderThread.h class WindowsGameRenderThread : public GameRenderThread { private: HANDLE renderThreadHandle; DWORD renderThreadID; Game *game; bool timeToProcessData; bool timeToRender; HANDLE timeToProcessDataMutex; HANDLE timeToRenderMutex; HANDLE renderingRenderListMutex; …

20 WindowsGameRenderThread.cpp WindowsGameRenderThread::WindowsGameRenderThread() { renderThreadHandle = NULL; timeToProcessData = true; timeToRender = false; timeToProcessDataMutex = CreateMutex(0, NULL, L"timeToProcessDataMutex"); timeToRenderMutex = CreateMutex(0, NULL, L"timeToRenderMutex"); renderingRenderListMutex = CreateMutex(0, NULL, L"renderingRenderListMutex"); }

21 WindowsGameRenderThread.cpp void WindowsGameRenderThread::start(Game *game) { // START THE RENDER THREAD HANDLE renderThreadHandle; unsigned int renderThreadID; renderThreadHandle = (HANDLE)_beginthreadex( NULL, 0, &RenderThread, game, 0, &renderThreadID ); setRenderThreadHandle(renderThreadHandle); setRenderThreadID(renderThreadID); }

22 void WindowsGameRenderThread::runFromMainThread(Game *game) { WaitForSingleObject(timeToProcessDataMutex, INFINITE); if (timeToProcessData) { timeToProcessData = false; game->processGameData(); ReleaseMutex(timeToProcessDataMutex); // NOW LET'S SWAP THE RENDER LISTS WaitForSingleObject(renderingRenderListMutex, INFINITE); GameGraphics *graphics = game->getGraphics(); graphics->swapRenderLists(); ReleaseMutex(renderingRenderListMutex); WaitForSingleObject(timeToRenderMutex, INFINITE); timeToRender = true; ReleaseMutex(timeToRenderMutex); } else ReleaseMutex(timeToProcessDataMutex); } Called each frame by main thread

23 unsigned __stdcall RenderThread( void* pArguments ) { Game *game = (Game*)pArguments; GameGraphics *graphics = game->getGraphics(); WindowsGameRenderThread *thread = (WindowsGameRenderThread*)game->getRenderThread(); while (game->isGameActive()) { WaitForSingleObject(thread->getTimeToRenderMutex(), INFINITE); if (thread->isTimeToRender()) { thread->setTimeToRender(false); ReleaseMutex(thread->getTimeToRenderMutex()); WaitForSingleObject(thread->getRenderingRenderListMutex(), INFINITE); int gameMode = game->getGameMode(); if ((gameMode != LEVEL_LOADING_GAME_MODE) && (gameMode != LEVEL_UNLOADING_GAME_MODE)) graphics->renderGameInRenderThread(game); Render Thread

24 ReleaseMutex(thread->getRenderingRenderListMutex()); WaitForSingleObject(thread->getTimeToProcessDataMutex(), INFINITE); thread->setTimeToProcessData(true); ReleaseMutex(thread->getTimeToProcessDataMutex()); } else { ReleaseMutex(thread->getTimeToRenderMutex()); } _endthreadex( 0 ); return (26); } Render Thread

25 References Coding For Multiple Cores on Xbox 360 and Microsoft Windows –http://msdn2.microsoft.com/en-us/library/bb204834(VS.85).aspxhttp://msdn2.microsoft.com/en-us/library/bb204834(VS.85).aspx


Download ppt "CSE 380 – Computer Game Programming Render Threading Portal, by Valve,"

Similar presentations


Ads by Google