29
Внедрение параллельного рендеринга в игровой движок Роман Лут, Ведущий программист, Deep Shadows

Внедрение параллельного рендеринга в игровой движок

Embed Size (px)

DESCRIPTION

Презентация заняла второе место в Intel Game Demo 2008 contest.

Citation preview

Page 1: Внедрение параллельного рендеринга в игровой движок

Внедрение параллельного

рендеринга в игровой движок

Роман Лут,Ведущий программист,

Deep Shadows

Page 2: Внедрение параллельного рендеринга в игровой движок

Кратко о себе

Распараллеливание – необходимость: “Free lunch is over”

Минимальная конфигурация – Core 2 Duo, “обычные” игры используют 50% CPU

Ведение

Page 3: Внедрение параллельного рендеринга в игровой движок

Создаем несколько потоков и делаем в них что-нибудь

«Плохая» многопоточность

Результат: полная неразбериха, ничего не работает

Page 4: Внедрение параллельного рендеринга в игровой движок

Распараллеливанию программы мешает её линейный характер исполнения - следующий блок использует данные, созданные предыдущим.

Первый шаг: анализ системы, разделение ее на относительно независимые компоненты с минимальным, с четко описанным взаимодействием.

Выбор модели распараллеливания

Анализ, разделение

Page 5: Внедрение параллельного рендеринга в игровой движок

Модель 1: Независимые компоненты движка работают в разных потоках

Рендеринг игрового мира

Апдейт состояния игрового мира

Апдейт состояния игрового мира

Апдейт состояния игрового мира

Рендеринг игрового мира

Рендеринг игрового мира

Page 6: Внедрение параллельного рендеринга в игровой движок

+ относительно простая реализация, но при наличии достаточно независимых компонентов.

+ простое и понятное взаимодействие компонентов в параллельном приложении

- плохая масштабируемость вверх- необходимость хранения двух состояний

мира (готовое, и текущее рассчитываемое - аналогично front и back buffers в графике).

- отсутствие балансировки загрузки ядер (одна из систем всегда будет ожидать другую).

Модель 1: Плюсы и минусы

Page 7: Внедрение параллельного рендеринга в игровой движок

Модель 2: Producer - consumer

Рендеринг объекта

Апдейт объекта

Page 8: Внедрение параллельного рендеринга в игровой движок

+ относительная простота реализации

+ сохраняется линейная логика исполнения программы

+ возможность реализации дополнительной функциональности (сортировка по render states)

 - плохая масштабируемость- отсутствие балансировки загрузки

ядер

Модель 2: Плюсы и минусы

Page 9: Внедрение параллельного рендеринга в игровой движок

Модель 3: Расщепление нити исполнения

Block 2

Block 3

Block 4

Block 2

Block 3

Block 4

Block 1

Block 1

Sync

Page 10: Внедрение параллельного рендеринга в игровой движок

+ сохраняется относительно линейная последовательность исполнения

+ относительно простая реализация в существующем коде

- возможности оптимизации ограничены

- неэффективная загрузка ядер

- плохая масштабируемость вверх

Модель 3: Плюсы и минусы

Page 11: Внедрение параллельного рендеринга в игровой движок

Модель 4: Task dependency graph

Block 2

Block 8

Block 4

Block 1

Block 5

Block 7

Block 3

Block 6

Block 10

Block 9

Page 12: Внедрение параллельного рендеринга в игровой движок

+ отличная масштабируемость+ максимально эффективная загрузка

доступных ядер+ можно расширить систему, добавив

задачи для SPU, CUDA. - "динамическая система" со всеми

свойственными недостатками: - непредсказуемый порядок исполнения; - сложность отладки - требует полного пересмотра архитектуры

движка (нужно переписать все "с нуля")

Модель 4: Плюсы и минусы

Page 13: Внедрение параллельного рендеринга в игровой движок

Для справки: от момента создания потока до начала его выполнения может пройти до 100 мс

Нужна библиотека более высокого уровня

Задачи в ITBB: tbb::task.spawn(), tbb::task.waitforall()

+содержит контейнеры с поддержкой многопоточности, примитивы синхронизации, параллельные алгоритмы и т.д.

www.thredingbuildingblocks.org

Intel Threading Building Blocks

Page 14: Внедрение параллельного рендеринга в игровой движок

Никогда нет времени сделать все оптимально! ( реальность программирования ).

“Идеальное” решение не является требованием. Требование - обеспечить 30FPS с имеющимся контентом.

Producer-consumer и Расщепление нити исполнения не требуют глобального изменения кода.

Выбор архитектуры

Page 15: Внедрение параллельного рендеринга в игровой движок

Ситуация до оптимизации

Page 16: Внедрение параллельного рендеринга в игровой движок

Ситуация до оптимизации

Page 17: Внедрение параллельного рендеринга в игровой движок

Ситуация до оптимизации

Page 18: Внедрение параллельного рендеринга в игровой движок

Producer-consumer рендеринга

Обход сцены Апдейт мира

Ring buffer

Рендериг

Page 19: Внедрение параллельного рендеринга в игровой движок

Producer-consumer рендеринга

Page 20: Внедрение параллельного рендеринга в игровой движок

Producer-consumer рендеринга

Page 21: Внедрение параллельного рендеринга в игровой движок

Producer-consumer рендеринга

Результат: повышение FPS на

>150% !

Page 22: Внедрение параллельного рендеринга в игровой движок

Producer-consumer рендеринга: детали реализации

Очень не хочется перерабатывать весь код

Хочется оставить возможность рендерить по-старому

Решение: включение/отключение параллельного рендеринга «на лету»

Внутри методов API графической библиотеки либо записывать команды в Ring Buffer, либо выполнять сразу

Проверка условия: bParallelrenderingEnabled && GetCurrentThreadId() != RenderingThreadId

Page 23: Внедрение параллельного рендеринга в игровой движок

Producer-consumer рендеринга: детали реализации

В Ring buffer складываются классы, наследованные от TRBRecord, с помощью placement new()

Класс содержит в себе все параметры для вызова метода графического API

Метод Run() вызывает метод API Зацикливание не происходит

благодаря проверке GetCurrentThreadId() != RenderingThreadId

Page 24: Внедрение параллельного рендеринга в игровой движок

Producer-consumer рендеринга: детали реализации

void TRenderStateFactory::SetWorldMatrix(const TMATRIX4x3* matWorld)

{ if ( RenderLib.renderThreading.IsRecordingThread() ) { VE_FIRE_RING_BUFFER_EVENT_P(TRBRSetWorldMatrix,

matWorld); return; }

m_WorldMatrix = *matWorld;RenderLib.VertexShaderFactory.ConstantCache.InvalidateConst

ants(VSHC_WORLDVIEWMATRIX);}

Page 25: Внедрение параллельного рендеринга в игровой движок

Producer-consumer рендеринга: детали реализации

class TRBRSetWorldMatrix : public TRBRecord { public: TRBRSetWorldMatrix(const TMATRIX4x3* worldMatrix) { m=*worldMatrix; } virtual bool Run() { RenderLib.RenderStateFactory.SetWorldMatrix(&m); return true; } private: TMATRIX4x3 m; };

Page 26: Внедрение параллельного рендеринга в игровой движок

Producer-consumer рендеринга: выводы

«Однонаправленный» API – хорошая линия раздела для producer-consumer модели

Быстрая реализация, хороший результат

Глобальные переменные – враги распараллеливания

Page 27: Внедрение параллельного рендеринга в игровой движок

Emergent DirectX command buffer library

Producer-consumer для DirectX API

Используется в Gamebryo

Open Source library: http://www.emergent.net/GameFest20

08

Page 28: Внедрение параллельного рендеринга в игровой движок

Future work

Убрать глобальные переменные и контексты!

Расщепление нити исполнения, на основе tbb::task

Page 29: Внедрение параллельного рендеринга в игровой движок

Вопросы ? Intel Threading BuildingBlocks www.threadingbuildingblocks.org

Vincent Scheb, GameBrio, Emergent game technologies, “Practical Parallel rendering with DirectX 9 and 10”, http://emergent.net/GameFest2008

“Emergent open source Command Buffer library”, http://emergent.net/GameFest2008  Jim Tilander, Vassily Filippov, Sony Santa Monica, “Practical SPU Programming in God of War III”  Capcom lecture, “Capcom MT framework”,

Capcom lecture, “Lost planet multithreaded rendering”  Ville Mönkkönen , Gamasutra, “Multithreaded game engine architectures”  Henry Gabb and Adam Lake, Gamasutra, “Threading 3D Game Engine Basics”

Jonathan Haas, Game Technology Group, Microsoft, "Designing Multi-Core Games: How to Walk and Chew Bubblegum at the Same Time“

Abdennour El Rhalibi, Dave England and Steven Costa, "Game Engineering for a Multiprocessor Architecture”

Tom Leonard, Valve, "Dragged Kicking and Screaming: Source Multicore“

Will Damon, Engineer Software Solutions Group, Intel Corporation "Multithreading Your Game Engine for Hyper-Threading Technology“

Leigh Davies, Senior Application Engineer, INTEL, "Optimizing DirectX on Multi-core architectures“

Maxim Perminov, Aaron Coday, Will Damon, "Real World Multithreading in PC Games Case Studies"