1 / 47

Technical Architect Ubisoft Montreal

Squeeze the Juice out of CPUs Post Mortem of a Data-Driven Scheduler. Remi QUENIN. Michael LAVAIRE. Technical Lead Ubisoft Montreal. Technical Architect Ubisoft Montreal. Table of Contents. Issues on common MT Archi . “Shears” Solution Tips and Tricks. Usual multithreading patterns.

bozica
Télécharger la présentation

Technical Architect Ubisoft Montreal

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Squeeze the Juice out of CPUs Post Mortem of a Data-Driven Scheduler Remi QUENIN Michael LAVAIRE Technical Lead Ubisoft Montreal Technical Architect Ubisoft Montreal

  2. Table of Contents Issues on common MT Archi. “Shears” Solution Tips and Tricks

  3. Usual multithreading patterns 1. Common architectural DesignS

  4. Folded loop Smaller Engine Loop Gameplay Thread 1 Graphic Thread 2 Engine Loop Background Loading Thread 3 Frame N N+1 N+2

  5. Sync point Applying modifications Applying modifications Applying modifications Gameplay Sync Sync Graphic Sync Sync Applying modifications Background Loading

  6. Tasks Scheduling Stage 1 Stage 2 Stage 3 Task C Task E Task A Task D Gate Task B Task F Waiting

  7. 60 FPS for everyone 2. « SHEARS » SOLution

  8. Objectives

  9. Focus on data, not on the code 2.1 Data Driven Scheduling

  10. Data drivenscheduling Data D0 Task A Task A Task A Task A Task A Task A Task A Data D0 Task C Task A Task A Task A Task B Data D1 Data D1

  11. Data drivenscheduling Data D0 D0 D1 Task A Task A Task A Task A Task A Task A Task A Task C Task A Task A Task A Task B Data D1

  12. Data driven scheduling D0 D1 Task A Task B Task C

  13. Data driven scheduling D0 D1 Task A Task B Task C

  14. Data drivenscheduling

  15. Data drivenscheduling

  16. Data drivenscheduling

  17. No locks, be scalable 2.2 workloads

  18. Workload

  19. Lock-free : Internal Thread 1 Container::Add() Thread 2 Container::Remove() Container State State State State State State State Test &Set Test &Set SUCCESS ! FAILED ! SUCCESS !

  20. Lock-free

  21. Lock-free : Comparison Q6600

  22. Lock-free : Comparison X360

  23. Lock-free : Comparison PS3

  24. Easy cross-platforming, easydebugging 2.3 Workingwith SPU

  25. Working with SPUCross Platform API ?

  26. Working with SPUCross Platform API DMA Impl Main Memory Impl Memory Access Interface SatelliteTask

  27. Working with SPU Easy Debugging DMA Impl Main Memory Impl Memory Access Interface SatelliteTask

  28. Working with SPUEasy Debugging

  29. Working with SPU Easy Debugging Named Pipe DMA Impl Main Memory Impl Memory Access Interface SatelliteTask

  30. Multithreading & peace of mind 3. Tips & tricks

  31. Tip 1: Clever profiling

  32. Tip 2: Watchdog

  33. Tip 3: Unit Tests

  34. Trick 1: Perturbation

  35. Trick 1: Perturbation Loop n Loop n+1 Test A Test B Test A Test B Thread A Test C Test D Test C Test D Thread B New thread synchronization

  36. Trick 2: State validation

  37. Trick 2: State validation Process A Process B Process C State 1 State 2 State 3 State X Assert ! Process X

  38. Trick 2: State validation classStateChecker { public: enum State { State1, State2, State3 }; StateChecker() { m_state = State1; } boolSetState( State oldState, State newState ) { return Atomic::TestAndSet ( &m_state, oldState, newState ) == oldState; } private: volatile State m_state; };

  39. Trick 3: Access verification

  40. Trick 3: Access verification classAccessChecker { public: AccessChecker() { m_access = 0; } boolStartReadAccess() { returnAtomic::Inc( &m_access ) > 0; } boolEndReadAccess() { returnAtomic::Dec( &m_access ) >= 0; } boolStartWriteAccess() { return Atomic::Dec( &m_access ) == -1; } boolEndWriteAccess() { return Atomic::Inc( &m_access ) == 0; } private: volatileintm_access; };

  41. Trick 4: Multithreaded Assert

  42. Trick 4: Multithreaded Assert extern volatile boolg_waitOnAssert = false; #define ASSERT( condition ) \while(g_waitOnAssert) {} \if( !(condition) ) \{ \g_waitOnAssert = true; \DoAssert(); \g_waitOnAssert = false; \}

  43. Squeeze the Juice !

  44. Inspiration • Game Programming Gems 6: Lock-free Algorithmsby Toby Jones • Design and Implementation of Multi-Threaded Gamesby Bruce Dawson • Floodgate: Maximizing SPU parallelism without sacrificing cross platform developmentby David Asbell & Michael Noland • SPU Shadersby Mike Acton

  45. michael.lavaire@ubisoft.com remi.quenin@ubisoft.com

  46. Ubisoft is recruiting!Come see us at the Ubisoft Booth in the Career Pavilion (CP 2308, South Hall)You can also check out:www.creatorsofemotions.com

More Related