• Nebyly nalezeny žádné výsledky

BOHEMIA INTERACTIVE Datově orientovaný model

N/A
N/A
Protected

Academic year: 2022

Podíl "BOHEMIA INTERACTIVE Datově orientovaný model"

Copied!
49
0
0

Načítání.... (zobrazit plný text nyní)

Fulltext

(1)

BOHEMIA INTERACTIVE

Datově orientovaný model

Xeniya Vondrášková, Filip Vondrášek

15. 5. 2019, MFF UK

(2)

Kdo jsme?

Pracujeme v Bohemia Interactive jako gameplay programátoři.

Náš projekt je Ylands -- sandboxová hra a platforma pro vytváření vašich vlastních her.

V současné době na Steamu v Early Accessu.

(3)

PLÁN

1. Rozložení paměti struktur 2. CPU cache

3. Datově orientovaný design

4. Unity DOTS (Entity Component System)

GDS 2018

(4)

ROZLOŽENÍ PAMĚTI

STRUKTUR

(5)

Rozložení paměti struktur

public struct NPCData {

public Vector3 Position;

public byte IsPositionCurrent;

public Quaternion BodyOrientation;

public byte IsOrientationCurrent;

public int Health;

public byte HasEverTakenDamage;

public int Damage;

public byte HasEverShot;

public Quaternion HeadOrientation;

}

LS 2019 01/ Rozložení paměti struktur

(6)

Rozložení paměti struktur

unsafe {

Debug.Log(sizeof(NPCData));

} 68

LS 2019 02/ Rozložení paměti struktur

(7)

public struct NPCData {

public Quaternion BodyOrientation;

public Quaternion HeadOrientation;

public Vector3 Position;

public int Health;

public int Damage;

public byte IsPositionCurrent;

public byte IsOrientationCurrent;

public byte HasEverTakeDamage;

public byte HasEverShot;

}

Rozložení paměti struktur

LS 2019 03/ Rozložení paměti struktur

(8)

Rozložení paměti struktur

unsafe {

Debug.Log(sizeof(NPCData));

} 56

LS 2019 04/ Rozložení paměti struktur

(9)

Rozložení paměti struktur

LS 2019 05/ Rozložení paměti struktur

12 bytů méně - proč?

Odpověď je rozložení paměti

C# (stejně jako C/C++) jde shora dolů a skládá prvky struktur do paměti v tomto pořadí

Každý datový typ má přirozené zarovnání, které musí být dodrženo, aby CPU mohl číst a zapisovat paměť efektivně.

Pokud není paměť zarovnána, namísto jednoduchého čtení/zápisu musí CPU přečíst více bloků paměti, aplikovat masku, bit shift a OR operaci.

(10)

LS 2019 06/ Rozložení paměti struktur

public struct WrongLayout {

public Vector3 Position;

public byte IsPositionCurrent;

public Quaternion BodyOrientation;

public byte IsOrientationCurrent;

public int Health;

public byte HasEverTakenDamage;

public int Damage;

public byte HasEverShot;

public Quaternion HeadOrientation;

}

Rozložení paměti struktur

(11)

LS 2019 07/ Rozložení paměti struktur

public struct WrongLayout {

→ public Vector3 Position;

public byte IsPositionCurrent;

public Quaternion BodyOrientation;

public byte IsOrientationCurrent;

public int Health;

public byte HasEverTakenDamage;

public int Damage;

public byte HasEverShot;

public Quaternion HeadOrientation;

}

Rozložení paměti struktur

(12)

LS 2019 08/ Rozložení paměti struktur

public struct WrongLayout {

public Vector3 Position;

→ public byte IsPositionCurrent;

public Quaternion BodyOrientation;

public byte IsOrientationCurrent;

public int Health;

public byte HasEverTakenDamage;

public int Damage;

public byte HasEverShot;

public Quaternion HeadOrientation;

}

Rozložení paměti struktur

(13)

LS 2019 09/ Rozložení paměti struktur

public struct WrongLayout {

public Vector3 Position;

public byte IsPositionCurrent;

→ public Quaternion BodyOrientation;

public byte IsOrientationCurrent;

public int Health;

public byte HasEverTakenDamage;

public int Damage;

public byte HasEverShot;

public Quaternion HeadOrientation;

}

Rozložení paměti struktur

(14)

10/ Rozložení paměti struktur

public struct WrongLayout {

public Vector3 Position;

public byte IsPositionCurrent;

→ public Quaternion BodyOrientation;

public byte IsOrientationCurrent;

public int Health;

public byte HasEverTakenDamage;

public int Damage;

public byte HasEverShot;

public Quaternion HeadOrientation;

}

Rozložení paměti struktur

LS 2019

(15)

LS 2019 11/ Rozložení paměti struktur

public struct WrongLayout {

public Vector3 Position;

public byte IsPositionCurrent;

public Quaternion BodyOrientation;

→ public byte IsOrientationCurrent;

public int Health;

public byte HasEverTakenDamage;

public int Damage;

public byte HasEverShot;

public Quaternion HeadOrientation;

}

Rozložení paměti struktur

(16)

LS 2019 12/ Rozložení paměti struktur

public struct WrongLayout {

public Vector3 Position;

public byte IsPositionCurrent;

public Quaternion BodyOrientation;

public byte IsOrientationCurrent;

→ public int Health;

public byte HasEverTakenDamage;

public int Damage;

public byte HasEverShot;

public Quaternion HeadOrientation;

}

Rozložení paměti struktur

(17)

LS 2019 13/ Rozložení paměti struktur

public struct WrongLayout {

public Vector3 Position;

public byte IsPositionCurrent;

public Quaternion BodyOrientation;

public byte IsOrientationCurrent;

public int Health;

→ public byte HasEverTakenDamage;

public int Damage;

public byte HasEverShot;

public Quaternion HeadOrientation;

}

Rozložení paměti struktur

(18)

LS 2019 14/ Rozložení paměti struktur

public struct WrongLayout {

public Vector3 Position;

public byte IsPositionCurrent;

public Quaternion BodyOrientation;

public byte IsOrientationCurrent;

public int Health;

public byte HasEverTakenDamage;

→ public int Damage;

public byte HasEverShot;

public Quaternion HeadOrientation;

}

Rozložení paměti struktur

(19)

LS 2019

public struct WrongLayout {

public Vector3 Position;

public byte IsPositionCurrent;

public Quaternion BodyOrientation;

public byte IsOrientationCurrent;

public int Health;

public byte HasEverTakenDamage;

public int Damage;

→ public byte HasEverShot;

public Quaternion HeadOrientation;

}

Rozložení paměti struktur

15/ Rozložení paměti struktur

(20)

LS 2019

public struct WrongLayout {

public Vector3 Position;

public byte IsPositionCurrent;

public Quaternion BodyOrientation;

public byte IsOrientationCurrent;

public int Health;

public byte HasEverTakenDamage;

public int Damage;

public byte HasEverShot;

→ public Quaternion HeadOrientation;

}

Rozložení paměti struktur

16/ Rozložení paměti struktur

(21)

CPU CACHE

LS 2019 17/ CPU cache

(22)

CPU CACHE

Instrukční cache (L1i, L2, L3...) Datové cache (L1d, L2, L3...)

L1 a L2 většinou samostatná pro každé jádro procesoru L3 sdílená mezi jádry

L1, L2, L3 typicky SRAM

L4 ve specializovaných procesorech, DRAM, mimo CPU kostku

LS 2019 18/ CPU cache

(23)

NAČÍTÁNÍ DAT DO CPU

Procesor dostane instrukci “přečti data z adresy XYZ”

Data už jsou v cache -> cache hit Data nejsou v cache -> cache miss

Cache miss: Musíme naalokovat místo v cache, přečíst data z RAM, pak teprve přečíst do registrů.

Výpočetně velmi náročné (zvlášť u write-back systémů) Cache line - data jsou načítaná po blocích fixní velikosti

LS 2019 19/ CPU cache

(24)

ČASOVÁ NÁROČNOST TYPICKÝCH OPERACÍ

LS 2019 20/ Časová náročnost operací

Operace Čas

Čtení z L1 cache

0,5 ns

Provedení instrukce

1 ns

Branch misprediction

5 ns

Čtení z L2 cache

7 ns

Čtení z RAM

100 ns (200x pomalejší než L1 cache!)

Přečtení 1 MB RAM sekvenčně

250 000 ns

Přečtení 1 MB SSD sekvenčně

1 000 000 ns

Přečtení 1 MB HDD sekvenčně

20 000 000 ns

(25)

PROBLÉMY RYCHLOSTI PAMĚTÍ

CPU stall - Při čekání na cache line nemá CPU nic co na práci. Za čas, co CPU čeká na data, by jinak zvládl zpracovat stovky instrukcí - bottleneck

Mitigace: out-of-order execution - provádění následujících operací, které nejsou závislé na očekávaných datech.

Dále simultánní multithreading (např. Intel Hyper-Threading) - zatímco aktivní vlákno v CPU čeká na zdroje, po tu dobu může pracovat jiné vlákno.

LS 2019 21/ Problémy paměti

(26)

DATOVĚ ORIENTOVANÝ

DESIGN

(27)

LOREM IPSUM DOLOR SIT AMET

LS 2019 22/ Datově orientovaný design

(28)

DRUHY PROGRAMOVACÍCH PŘÍSTUPŮ

Objektově orientované programování - C++, C#, Java…

Funkcionální programování - Prolog, Lisp...

Procedurální programování - C

Datově orientované programování - ?

LS 2019 23/ Datově orientovaný design

(29)

PŘÍKLAD DATOVÉ CACHE

class Character {

float HP; // 4 float Stamina; // 4

Vector3 Position; // 3 floats -> 12 Quaternion Rotation; // 4 floats -> 16 bool IsAlive; // 1

};

class NPC: Character

{

Color HairColor; // 4 floats -> 16 };

LS 2019 24/ Datově orientovaný design

(30)

PŘÍKLAD DATOVÉ CACHE

class Character {

float HP; // 4 float Stamina; // 4

Vector3 Position; // 3 floats -> 12 Quaternion Rotation; // 4 floats -> 16 bool IsAlive; // 1

};

class NPC: Character

{

Color HairColor; // 4 floats -> 16 };

LS 2019 25/ Datově orientovaný design

class NPC

size(56)

: +---

0 | +--- (base class Character) 0 | | HP

4 | | Stamina

8 | | Vector3 Position 20 | | Quaternion Rotation 36 | | IsAlive

| | <alignment member> (size=3)

| +---

40 | Color HairColor +---

(generated on https://godbolt.org using x64 msvc v19.15 with the

/d1reportSingleClassLayoutNPC compiler option)

(31)

for (int i=0; i< NPCCount; i++) {

NPCs[i].Move(deltaTime);

}

void NPC::Move(float deltaTime) {

Position.x += AI.xDir * deltaTime;

Position.y += AI.yDir * deltaTime;

Position.z += AI.MoveUp ? deltaTime : 0f;

}

LS 2019 26/ Datově orientovaný design

PŘÍKLAD DATOVÉ CACHE

(32)

for (int i=0; i< NPCCount; i++) {

NPCs[i].Move(deltaTime);

}

void NPC::Move(float deltaTime) {

Position.x += AI.xDir * deltaTime;

Position.y += AI.yDir * deltaTime;

Position.z += AI.MoveUp ? deltaTime : 0f;

}

LS 2019 27/ Datově orientovaný design

8 byte 8 byte 8 byte 8 byte 8 byte 8 byte 8 byte 8 byte

NPC0 Position NPC1

Position NPC2 Position

NPC3 Position NPC4 Position

NPC5 Position NPC6 Position

NPC7 Position

NPC8 Position NPC9

Position NPC10 Position

NPC11 Position NPC12 Position

NPC13 Position NPC14 Position

NPC15 Position

NPC16 Position NPC17

PŘÍKLAD DATOVÉ CACHE

(33)

LS 2019 28/ Datově orientovaný design

(34)

OOP

Zapouzdření (Encapsulation):

Schovávání informací V podstatě jen read/write

Dědičnost (Inheritance):

Třídy dědí ze svých předků

Rozšiřování, případně přepisování vlastností předků

LS 2019 29/ Datově orientovaný design

Polymorfismus (Polymorphism):

Schopnost zpracovávat objekty různými způsoby v závislosti na jejich typu nebo třídě.

Třídy (Classes):

Data + chování v jedné “obálce”

(35)

DOD

LS 2019 30/ Datově orientovaný design

Nejčastěji využíván při vývoji her Důraz na uspořádání dat v paměti

Není o struktuře kódu, ale o struktuře dat: seskupení dat podle využití, ne podle logického modelu

Minimum objektů, většinou jen systémy, které manipulují s daty Redukce cache missů - mitigace pomalé paměti oproti CPU

(36)

Příklad : OOP vs DOD

LS 2019 31/ Datově orientovaný design

struct Ball { Point position;

Color color;

double radius;

void draw();

};

vector<Ball> balls;

Array of Structs (AoS):

---

| position | color | radius | position | color | radius | position | color | … ---

(37)

Příklad : OOP vs DOD

LS 2019 32/ Datově orientovaný design

struct Balls {

vector<Point> position;

vector<Color> color;

vector<double> radius;

void draw();

};

Struct of Arrays (SoA):

---

| position | position | position | color | color | color | radius | radius | ...

---

(38)

VÝHODY DOD

LS 2019 33/ Datově orientovaný design

Efektivní využití cache CPU Snadná paralelizace

Modularita

(39)

NEVÝHODY DOD

LS 2019 34/ Datově orientovaný design

Zcela jiný programovací přístup než OOP Nízké využití vlastností jazyka

Netriviální propojení s již existujícím OOP/procedurálním kódem

(40)

DOD V PRAXI

(41)

Unity DOTS (Data Oriented Technology Stack)

LS 2019 35/ DOD v praxi

V Unity poprvé představen ve verzi 2018.1 jako experimentální balíček.

Obsahuje tři hlavní aspekty, které by měly výrazným způsobem zlepšit výkon výsledného produktu:

Entity-Component-System (ECS): stará se o rozložení paměti.

C# Job System: multi-threading.

Burst compiler: vysoce optimalizovaný strojový kód.

(42)

Unity: Tradiční přístup

ECS je nový architektonický návrh. Zakládá se na myšlence, že vývojáři začnou používat DOD namísto klasického OOP.

Tradiční přístup:

● GameObjects + Components + MonoBehaviour

LS 2019 36/ DOD v praxi

Minion Transform Collider Rigidbody Animator

ChasePlayer.cs

StealItems.cs

(43)

Entity Component System

LS 2019 37/ DOD v praxi

Rozložení objektů na různé komponenty (pozice, rotace, počet životů…)

Komponenty stejného typu (nezávisle na entitě, která je vlastní) chceme vyrovnat za sebe lineárně do paměti -> ideální na zpracování velkého množství objektů O zpracování dat se starají systémy, které pracují nad množinou komponent

(44)

V ECS rozdělujeme celou strukturu hry na:

Entity: “ID”

Komponenty: Struktury obsahující pouze instance dat pro entitu. Neobsahuje metody.

Systémy: Obsahují funkcionalitu/logiku. Zodpovědné za update všech entit s odpovídající množinou komponent.

ECS garantuje lineární datový layout - rychlejší management dat.

Také separuje data od logiky - snadnější aplikování instrukcí na velké množství entit paralelně.

Unity: Entity Component System

LS 2019 38/ DOD v praxi

(45)

Unity: Entity Component System

LS 2019 39/ DOD v praxi

Player

Minion

Enemy Boss

Position

Position

Position AI agent

AI agent XP

HP

HP

HP ...

...

...

AI behaviour system

Health system

XP system

Components set filter:

HP

XP Components

set filter:

Components set filter:

AI agent HP Position

https://software.intel.com/en-us/articles/get-started-with-the-unity-entity-component-system-ecs-c-sharp-job-system-and-burst-compiler

(46)

TITLE DIVIDER 1

LOREM IPSUM DOLOR SIT AMET, CONSECTEUR ADIPISCING

Tradiční přístup

(47)

TITLE DIVIDER 1

LOREM IPSUM DOLOR SIT AMET, CONSECTEUR ADIPISCING

ECS (+Burst)

(48)

LS 2019

(49)

DĚKUJEME ZA POZORNOST

xeniya.valentova@bistudio.com filip.vondrasek@bistudio.com

Follow us on:

@bohemiainteract

facebook.com/BohemiaInteractive/

linkedin.com/company/bohemia-interactive/

Odkazy

Související dokumenty

CPU execution time =CPI × Number of instructions ×CPU clock cycle time CPU executiontime = CPI × Number of instructions. CPU

Nejhůře je na tom aplikace v React Native (380 Mb), která vyžadovala pětkrát více paměti než nativní aplikace a téměř třikrát více paměti než Flutter.. Ve

Osobnostně orientovaný model výchovy uplatňovaný v mateřských školách je charakterizován vztahem k dítěti, jenž je proměněn z autoritativního na vstřícný

Redukce „boilerplate“ kódu na minimum o Pokud máme v rámci aplikace separované vrstvy Model a ViewModel do PCL, můžeme v aplikaci použít Framework MVVMCross, který

Večer byl docela najedený, takže místo večeře snědl u televize jen 150gramový pytlík brambůrků a vypil půl litru pomerančového džusu.. Spolužačka Jarka posnídala

• veřejná Wi-Fi síť (nepracujte s internetovým bankovnictvím nebo

Procesor patří mezi hlavní výpočetní jednotky nejen osobních počítačů, ale také například chytrých mobilních telefonů.. mozek počítače, řídí jeho ostatní části

(However, the DFA represented in Fig. 5 is neither suffix nor factor automaton.) It is not so memory efficient like Balík’s implementation but it reduces main memory (or hard