En jämförelse mellan dataorienterad design och objektorienterad design

Relevanta dokument
Cacheminne Intel Core i7

PARALLELLISERING AV ALGORITMER PROCESSORER FÖR FLERKÄRNIGA

Hyper Threading Intels implementation av SMT. Datorarkitekturer med operativsystem - EITF60. Felix Danielsson IDA2

Cacheminne i en Intel Core 2 Duo-processor

CDC en jämförelse mellan superskalära processorer. EDT621 Campus Helsingborg av: Marcus Karlsson IDA

Föreläsning 1: Intro till kursen och programmering

Hyper-Threading i Intelprocessorer

Objektorienterad programmering

Öka prestanda i Shared-Cache multi-core processorer

DESIGN AV KOMPONENTBASERADE ENTITETSSYSTEM

Prestandapåverkan på databashanterare av flertrådiga processorer. Jesper Dahlgren

Emil Kristiansson Kurs: EDT621 Delmoment: Rapport. En introduktion till Smart cache

Universe Engine Rapport

Objektorienterad programmering

Föreläsning 1: Intro till kursen och programmering

PROGRAMMERING. Ämnets syfte. Kurser i ämnet

Lunds Tekniska Högskola Datorarkitektur med operativsystem EITF60. Superscalar vs VLIW. Cornelia Kloth IDA2. Inlämningsdatum:

Litteraturstudie. Utarbetat av Johan Korhonen, Kajsa Lindström, Tanja Östman och Anna Widlund

Imperativ programmering. Föreläsning 4

Cacheprobe: programbibliotek för extrahering av cacheminnesparametrar

Cache-koherens protokoll MESI och MOSI

Parallellprogrammering i C++ 17 EDT621 Datorarkitekturer med Operativsystem Viktor Lindgren

PROGRAMMERING. Ämnets syfte. Kurser i ämnet

Objektorienterade programmeringsspråk. Objektorienterade språk. Den objekt-orienterade modellen. Jämför med icke-oo

What Is Hyper-Threading and How Does It Improve Performance

Objektorienterad programmering, allmänt

Viktiga egenskaper hos ett program (Meyer): Objektorienterad programmering, allmänt. Vilka egenskaper vill vi att våra program ska ha?

Programmering B med Visual C

Definition DVG A06. Varför operativsystem? Operativsystem. Översikt. - Vad är ett operativsystem?

Inledande programmering med C# (1DV402) Introduktion till C#

DVG A06. Operativsystem, mm. Karlstads universitet Datavetenskap. DVG A06 Johan Eklund. Datavetenskap, Karlstads universitet 1

Pipelining i Intel 80486

LUNDS UNIVERSITET. Parallell exekvering av Float32 och INT32 operationer

Classes och Interfaces, Objects och References, Initialization

PROGRAMMERING. Ämnets syfte. Kurser i ämnet

Hantering av hazards i pipelines

Schemaläggnings metoderna AMP & SMP i en Multiprocessor

Multithreading in Intel Pentium 4 - Hyperthreading

HF0010. Introduktionskurs i datateknik 1,5 hp

Datorsystem 2 CPU. Förra gången: Datorns historia Denna gång: Byggstenar i en dators arkitektur. Visning av Akka (för de som är intresserade)

Minnesisolering för virtuella maskiner en hypervisorstudie

Jämförelse av skrivtekniker till cacheminne

Parallellism i NVIDIAs Fermi GPU

PROGRAMMERING. Ämnets syfte. Kurser i ämnet

Rapport (1,5 HP) Lunds Universitet HT15

Pipelining i Intel Pentium II

Multi-ported cache En rapport om några lösningar till att få flera minnesaccesser simultant.

Datorarkitekturer med Operativsystem

MESI i Intel Core 2 Duo

MESI-Protokollet. Richard Elvhammar. Lund Universitet 4/12-16

Cacheminne i en AMD Opteron Processor

32 Bitar Blir 64 Sammanfattning

Programmering. Seminarier i datavetenskap, datorteknik och informationsteknik. Niklas Broberg

Forskning och utveckling inom språkteknologi Uppgift 3: Projektförslag Parallelliserad dependensparsning i CUDA

MESI-protokollets funktion i multiprocessorer

Föreläsning 15: Repetition DVGA02

SKOLFS. beslutade den -- maj 2015.

729G75: Programmering och algoritmiskt tänkande. Tema 1, föreläsning 1 Jody Foo

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

Tentamen den 14 januari 2015 Datorarkitekturer med operativsystem, EDT621, 7,5 poäng

Aktivitetsschemaläggning för flerkärninga processorer

SKOLFS. beslutade den XXX 2017.

Datorhistorik. Föreläsning 3 Datorns hårdvara EDSAC. Eniac. I think there is a world market for maybe five computers. Thomas Watson, IBM, 1943

Att designa en vetenskaplig studie

Improved-MOESI Cache koherens Protokoll

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design Alex Gerdes, 2016

729G75: Programmering och algoritmiskt tänkande. Tema 1. Föreläsning 1 Jody Foo

Random Access Memory. Amare Reda Jenny Holmberg Henrik Kreipke Gaylord Kaya

Classes och Interfaces, Objects och References Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Mälardalens högskola

Programmering. Seminarier i datavetenskap, datorteknik och informationsteknik. Niklas Broberg

Fö 7: Operativsystem. Vad är ett operativsystem? Målsättning med operativsystem. Styr operativsystemet datorn?

Principles of subclasses. Objekt-orienterad programmering och design Alex Gerdes, 2018

F8 - Arv. ID1004 Objektorienterad programmering Fredrik Kilander

MESI protokollet och dess derivater

SIMD i Intel s P5- baserade Pentium MMX

The Intelligent Timer

Programmering A. Johan Eliasson

Föreläsning 2. Operativsystem och programmering

Introduktion. Klasser. TDP004 Objektorienterad Programmering Fö 2 Objektorientering grunder

Program & programmering

Introduktion till programmering

Opponenter: Erik Hansen Mats Almgren Respondent: Martin Landälv ioftpd-verktyg

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Diskprestanda Tester

Inledning. Vad är ett datorprogram, egentligen? Olika språk. Problemlösning och algoritmer. 1DV433 Strukturerad programmering med C Mats Loock

Grundläggande programmering med matematikdidaktisk inriktning för lärare som undervisar i gy eller komvux gy nivå, 7,5 hp

Spekulativ exekvering i CPU pipelining

Design av interaktiv multimedia. Läs i förväg om det som övningarna kommer att beröra. Träna hemma både före och efter övningarna.

Titel Mall för Examensarbeten (Arial 28/30 point size, bold)

Historik: OOP. Objektorientering. Historik: OOP (forts) En Dum Fråga

Mer OOP. Variation i typ. Medlen repetition. Generiska klasser. Gränssnitt - Interface. Mer om klasser Några exempel UML

SVAR TILL TENTAMEN I DATORSYSTEM, VT2013

Svar till tentamen den 16 december 2013 Datorarkitekturer med operativsystem, EDT621, 7,5 poäng

Processor pipelining genom historien (Intel i9-intel i7)

Undervisningen i ämnet programmering ska ge eleverna förutsättningar att utveckla följande:

Prestandajämförelse - Sekventiell skrivhastighet i RAID 4 och RAID 5

Objektorienterad Programkonstruktion

Programmering för alla!

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 6 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Transkript:

Kandidatarbete En jämförelse mellan dataorienterad design och objektorienterad design Författare: Charlotte Westerberg Handledare: Daniel Toll Termin: VT 2020 Ämne: Datavetenskap

Sammanfattning Dagens applikationer hanterar mer och mer data vilket resulterar i att de blir allt mer resurskrävande och kräver mer av hårdvaran. Vilket i förlängningen kan innebär att hårdvaran måste bytas ut med jämna mellanrum för att kunna köra mjukvaran på ett för användaren tillfredsställande sätt. Detta arbete undersöker om det genom att byta designteknik är möjligt att utveckla mindre resurskrävande applikationer. Arbetet presenterar en jämförelse mellan objektorienterad design (även kallad objektorienterad programmering, OOP) och data orienterad design (DOD). Detta genom att dels ta upp kända för- och nackdelar med respektive designteknik samt genom att utföra en mätning på respektive teknik. Det som anses vara de främsta fördelarna med OOP är återanvändning av kod, att koden är lätt att underhålla, säkerhet i form av inkapsling samt att objekten som används reflekterar den mänskliga verkligheten. Dessa fördelar är dock även något som bidrar till det som anses vara den främsta nackdelen med OOP, nämligen att den är prestandakrävande. När det gäller DOD så anses de främsta fördelarna vara att det medför en cachevänligare kod som leder till färre cachemissar. Det anses även vara lättare att parallellisera koden i jämförelse med OOP. Den nackdelen som tas upp med DOD är att de tar tid att lära sig och kräver en del övning. Dock är DOD väldigt okänt vilket resulterade i ett svagt underlag. Två simuleringar utvecklades i Unity varav den ena använder sig av den nya teknikstacken DOTS som är dataorienterad. Resultatet av mätningarna indikerar på att DOD använder mindre av hårdvaruresurserna vid prestandakrävande applikationer. Om applikationen ej är prestandakrävande märks dock ingen skillnad mellan de olika teknikerna vid fråga om processoranvändning. Nyckelord: Objektorienterad design, Data orienterad design, prestandamätning, processoranvändning, minnesanvändning, Unity, DOTS 1

Abstract Today, applications handle more and more data, which results in them becoming increasingly resource-intensive and requiring more of the hardware. Which in the long run may cause that the hardware must be replaced at regular intervals to be able to run the software in a way that is satisfactory for the user. This thesis investigates whether it is possible to get less resource-intensive applications by changing the design technology. The paper presents a comparison between object-oriented design (also known as object-oriented programming, OOP) and data-oriented design (DOD). This is performed by addressing the known advantages and disadvantages of each design technique and by measuring each technique in the matter of performance. What was considered to be the main advantages of OOP is the reuse of code, that the code is easy to maintain, security in the form of encapsulation and that the objects that are used reflect human reality. On the other hand, these advantages also contribute to what is considered to be the main disadvantage of OOP, namely that it is performance-intensive. When it comes to DOD, the main advantages are considered to be that it results in a more cache-friendly code that leads to fewer cache misses. DOD is also considered easier to parallelize the code compared to OOP. The disadvantage of DOD is that it is time consuming to learn and requires some practice. Though, DOD is very unknown which resulted in a narrow basis. Two simulations were developed in Unity, one of which uses the new technology stack DOTS, which is data-oriented. The results of the measurements indicate that DOD uses less of the hardware resources in performance-intensive applications. If the application is not performance-intensive, though, no difference is noticed between the different technologies when it comes to CPU-usage. Keywords: Object-oriented design, Data-oriented design, performance measurement, CPU-usage, memory usage, Unity, DOTS 2

Förord Jag vill självklart tacka min handledare Daniel Toll, för all den tid som han lagt ner på återkoppling och engagemang under denna uppsats gång. Jag vill även tacka min sambo som inspirerat mig till denna uppsatsidé och som även fungerat lite som bollplank under projekttiden. 3

Innehåll Begrepp 6 1 Introduktion 7 1.1 Bakgrund 7 1.2 Relaterade arbeten 8 1.2.1 Jämförelse mellan DOD och aggregationsbaserad design 9 1.2.2 Algoritm OOP vs DOD 10 1.3 Problemställning 12 1.4 Motivation 13 1.5 Mål 13 1.6 Avgränsningar 14 1.7 Målgrupp 14 1.8 Disposition 14 2 Teori 15 2.1 Hårdvaruresurser 15 2.2 Objektorienterad programmering (OOP) 16 2.3 Dataorienterad design (DOD) 16 2.4 Prestandamätning 17 3 Metod 18 3.1 Systematisk litteraturundersökning 18 3.2 Kontrollerade experiment 19 3.3 Tillförlitlighet och validitet 21 3.4 Etiska överväganden 22 4 Implementation 23 4.1 Beskrivning av simuleringen 23 4.1.1 OOP implementeringen 27 4.1.2 DOD/DOTS implementeringen 28 4.1.3 Objektstruktur 29 5 Resultat 30 5.1 Systematisk litteraturundersökning 30 5.2 Kontrollerade experiment 32 5.2.1 Framtagning av mätnivåer 32 5.2.2 Mätresultat 33 4

5.2.2.1 Miljö 1 34 6 Analys 44 6.1 Systematisk litteraturundersökning 44 6.2 Kontrollerade experiment 45 6.2.1 Miljö 1 45 6.2.2 Miljö 2 46 6.2.3 Miljö 3 47 6.2.4 Slutsats 48 7 Diskussion 50 7.1 Systematisk litteraturundersökning 50 7.2 Kontrollerade experiment 51 7.3 Relaterade arbeten 53 7.4 Slutsats 54 8 Sammanfattning och framtida arbete 56 Referenser 58 A Bilaga 1 Koden till simuleringarna 64 5

Begrepp Multitrådning (eng. Multithreading) - Innebär att mjukvara kan exekveras parallellt i två eller flera trådar. Flerkärniga processorer (eng. Multi-core) - Flera processorkärnor på samma chip vilket gör det möjligt att kunna använda multitrådning. Bildrutor per sekund (eng. Frames Per Second, FPS) - Antal nya bilder som skapas per sekund. Cachemissar - Uppstår när det efterfrågade datat inte finns i cachen och måste hämtas från minnet. Cachelinje - Enhet där dataöverföringen mellan cachen och minnet sker. Data-oriented Technology Stack (DOTS) - Unity s teknikstack baserad på DOD-tekniken. Stacken består av C# jobbsystemet, entitets komponentssystemet och burstkompilatorn. C# jobbsystemet (eng. C# Job System) - Möjliggör användandet av flerkärniga processorer. Entitets komponentssystemet (eng. Entity Component System) - Separerar variabler och funktioner. Burstkompilatorn (eng. Burst Compiler) - Konverterar C#-koden till maskinkod. OOP (objektorienterad programmering) - Koden organiseras upp i objekt som reflekterar den mänskliga världen. Objekten innehåller de variabler (data) och funktioner (beteende) som de själva använder. Objekten kommunicerar genom att skicka meddelande mellan varandra. DOD (dataorienterad design) - Koden organiseras upp i komponenter som innehåller variabler (data) samt system som innehåller funktioner (beteende). Systemen jobbar med de entiteter som innehåller specifika komponenter. 6

1 Introduktion Mjukvaran som utvecklas idag hanterar mer och mer data, blir allt mer komplex och kräver allt mer prestanda. Eftersom vi alla vill ha snabba applikationer som utnyttjar hårdvaran på bästa sätt är det intressant att undersöka om det går att få prestandakrävande applikationer att kräva mindre av hårdvarans tillgängliga resurser. Går det att genom att endast byta designteknik uppnå bättre prestanda och kommer vi i så fall att förlora någonting annat värdefullt på vägen? Den här rapporten kommer att presentera en jämförelse av prestanda mellan dagens stora programmeringsparadigm, objektorienterad design eller om man så vill objektorienterad programmering (OOP) samt den lite nyare och betydligt mer okända tekniken dataorienterad design (DOD). Den kommer även att belysa och diskutera fördelar och nackdelar med respektive teknik. 1.1 Bakgrund 1965 formulerade Gordon Moore en lag som benämndes Moore s lag [1, 2] med innebörden att processorns prestanda kommer att fördubblas med 18 månaders intervaller. Detta möjliggjorde att leverantörer kunde erbjuda antingen samma processor för halva priset eller en processor som var dubbelt så snabb till samma pris var 18:e månad. När denna snabba utveckling nådde fysiska begränsningar så började processortillverkare att sätta flera processorkärnor på samma chip vilket möjliggjorde att varje kärna kunde köra ett program och därmed kunde exekveringen ske parallellt. Flerkärniga processorer möjliggör multitrådning som innebär att vid program som skapar flera exekverande trådar så kommer operativsystemet att sprida dessa trådar över de processorer som finns tillgängliga. Detta leder till en god effektivitet men viktigt att tänka på är dock att om trådarna efterfrågar samma resurs som till exempel en specifik variabel så kommer den behöva låsas så att bara ena tråden får tillgång till den. Detta för att undvika konflikter. Det kan leda till att trådade program kan komma att spendera en hel del tid på att vänta [2]. Noel Llopis menar på att dataorienterad design (DOD) lämpar sig bättre på dagens hårdvara, i avseende på prestanda, än vad objektorienterad programmering (OOP) gör. Detta p g a hur data är organiserad inom de olika teknikerna. [3] Unity lanserade nyligen Data-Oriented Technology Stack (DOTS) som använder sig av DOD-tekniken. Stacken ska i jämförelse med OOP förbättra minneshanteringen [4], [5]. DOTS består av tre delar, första delen utgörs av C# jobbsystemet som möjliggör att man kan använda sig av flerkärniga processorer vilket gör att man kan exekvera parallella jobb samtidigt. Andra delen är entitets komponentsystemet som innebär att entiteter innehåller komponenter som i sin tur innehåller data och slutligen 7

system som sedan bearbetar detta datat. Man kan tänka sig att entitet motsvarar objekt, komponent innehåller variabler och system innehåller funktioner. Det blir alltså en separering mellan variabler och funktioner. Den sista delen är burstkompilatorn vars uppgift är att konvertera C#-koden till maskinkod [4]. Ett försök har visat att rita upp en mark bestående av 10 000 kuber tar 277 millisekunder med OOP kontra 41 millisekunder med DOTS [5]. Andra studier som är intressanta när det gäller DOD är en studie med en jämförelse mellan DOD och aggregationsbaserad design implementerad i C++. Där resultatet visade på att DOD gav upphov till färre cachemissar samt uppdaterade fler entiteter per sekund än den aggregationsbaserade designen [6]. När det gäller OOP i jämförelse med DOD har en mindre studie utförts på en algoritm implementerad både genom att använda OOP och DOD. Dessa skrivna i programmeringsspråket C. Studien visade att algoritmen implementerad utifrån DOD belastade processorn mindre [7]. Denna prestandaskillnad som studierna visar på blir intressant med tanke på att programmen som utvecklas hanterar mer och mer data och blir mer och mer prestandakrävande [8]. Den här rapporten kommer jämföra OOP och DOD genom att ta upp deras fördelar och nackdelar samt redovisa mätvärden i avseende på prestanda. 1.2 Relaterade arbeten När det gäller en identisk studie med mätning av prestanda genom jämförelse av FPS, minnesanvändning, processor- samt grafikprocessoranvändning mellan OOP och DOD finns inga sådana publicerade ännu som har kunnat hittats. Sökningen utfördes genom användning av diva-portalen, Google Scholar samt även Google. Sökorden som användes var object oriented design vs data oriented design performance/performance measurement och object oriented programming vs data oriented programming performance/performance measurement. Dessa sökningar utfördes även genom att använda de respektive förkortningarna OOD, OOP, DOD och DOP istället för att skriva ut hela namnen samt genom att översätta sökorden till svenska. Genom att läsa rubrikerna och läsa sammanfattningarna sållades intressanta resultat ut. De studier som hittats som relaterar en viss del till denna undersökning är beskrivna under rubrikerna nedanför. 8

1.2.1 Jämförelse mellan DOD och aggregationsbaserad design 2012 gjordes en studie som jämförde DOD och aggregationsbaserad design. Systemen som jämfördes var spel utvecklade i C++. Det som mättes i denna studie var uppdaterade entiteter per sekund och antal cachemissar per sekund. Entitet beskrivs i detta arbete som en sak i spelvärlden som har vissa egenskaper [6]. Ett annat sätt att tänka på en entitet är att det motsvarar ett specifikt objekt i OOP [4]. Cachemissar uppstår när det data som efterfrågas inte finns lagrat i cacheminnet och istället måste läsas in från minnet. Denna jämförelse visade att oberoende av indata så presterade det dataorienterade entitetssystemet bättre än det aggregationsbaserade. Anledningen till detta var dels att det dataorienterade entitetssystemet inte resulterade i lika många cachemissar vid entitets ökning. När mängden entiteter ökade från 10 000 till 100 000 visade det aggregationsbaserade entitetssystemet en 50 procentig prestandasänkning. Genom att gå från 10 miljoner uppdaterade entiteter per sekund till 5 miljoner uppdaterade entiteter per sekund. Medan det dataorienterade entitetssystemet visade på näst intill oförändrad prestanda, med cirka 23 miljoner uppdaterade entiteter per sekund. Vid ett ökat entitets dödstal påverkas dock prestandan för det dataorienterade entitetssystemet då en ökning av cachemissar uppstod samt en minskning till 15 miljoner uppdaterade entiteter per sekund. Dock presterade det fortfarande bättre än det aggregationsbaserade entitetssystemet vilket beror på hur skapande och borttagande av entiteter hanteras. Slutsatsen som drogs från mätningarna var att det dataorienterade entitetssystemet lämpade sig bättre i hänsyn till prestanda i ett spel körd på en hårdvara med minneshierarkie r [6]. Denna studie har jämfört ett aggregationsbaserade entitetssystem med ett dataorienterat entitetsystem och skiljer sig därmed från mitt arbete som jämför OOP med DOD. Mätvärden skiljer sig också åt då den här studien har mätt uppdaterade entiteter per sekund och antalet cachemissar medan mitt arbete jämför processoranvändning, FPS samt minnes- och grafikkortsanvändning. 9

1.2.2 Algoritm OOP vs DOD En mindre studie utfördes på en algoritm skriven i C implementerad både genom att använda OOP och DOD. Kompilatorn som användes i experimentet var GCC (GNU Compiler Collection). Denna artikel är av förklarliga skäl extra intressant för mitt arbete och kommer därför behandlas i detalj. Denna artikel är dock vad som benämns som grå litteratur så resultaten bör tolkas med större försiktighet än vid en artikel som blivit publicerad. Algoritmen som används för att utvärdera teknikerna loopar över en array som består av spelobjekt för att kontrollera två flaggor, deleted och is_visable. Om de är synliga så sparas indexvärdet i en variabel. I OOP implementeringen är båda flaggorna en del av datastrukturen. Detta innebär att processorn kommer hämta hela strukturens innehåll för att endast kontrollera true eller false på deleted och is_visable, till skillnad från DOD implementeringen där de är lagrade i fristående arrayer. I båda fallen är datastrukturen större än cachelinjen vilken kommer innebära att processorn inte kan lagra all data i L1-cachen. Detta resulterar i att data även måste hämtas från L2-, L3-cachen och i värsta fall från minnet. OOP implementationen kommer till skillnad från DOD behöva hämta en ny cachelinje för varje objekt. Studien visade att algoritmen implementerad utifrån DOD belastade processorn mindre. Dock utfördes studien på olika typer av processorer när array storleken bestod av fler än 10 000 element så började man se allt större skillnad mellan OOP- och DOD-implementeringen [7]. Detta går att se i figur 1.1 nedan. Värt att nämna efter min egen tolkning av graferna är även att Intel Core i7 7700HQ (mörkblå linje) betedde sig annorlunda på OOP-implementeringen. Den belastade alltid processorn mer i jämförelse med DOD-implementeringen. Men belastningen var större när arrayen bestod av 1 000-10 000 element, för att sedan vid en array storlek på 1 000 000 element, gå ner i belastning och närma sig DOD-implementeringen. En annan upptäckt som jag själv ställer mig frågande till i detta resultat är Intel Core i7 8700K (OOP, ljusblå linje), som vid 1 000 element har en processorcykel på 20.00. Medan den vid en ökning av 10 000 element går ner under 5.00 för att vid 100 000 element lägga sig strax under 25.00. Författaren kommenterade själv Intel Core i7 8700K som uppseendeväckande i den meningen att den vid en array storlek bestående av 10 000 element nästan var lika snabb som DOD implementeringen. Han nämner dock att han inte utfört några fler tester på detta [7]. Denna studie liknar min i det avseende att även den jämför OOP och DOD. Den skiljer sig dock genom att detta utförs på en algoritm skriven i C. Mitt arbete är en simuleringen skriven i C# med användning av Unity. Både denna studie och min studie mäter processoranvändningen. Dock mäter denna studie CPU cykler medan min studie mäter medelvärdet av hur lång tid processorn spenderar på varje frame i enheten millisekunder (ms). 10

Figur 1.1: Visar grafer över processoranvändningen för de olika processorerna samt implementeringen av DOD och OOP [7]. 11

1.3 Problemställning Problemet som ska undersökas är att DOD och OOP ska utvärderas och ställas mot varandra. Frågorna som skall granskas presenteras nedanför i figur 1.2. Som figuren visar så kan huvudfrågan, om det är möjligt att utveckla bättre applikationer genom att byta designteknik, brytas ner i fem mindre delfrågor. Dessa frågor leder alltså alla tillsammans fram till definitionen bättre applikationer. Den högra delen av delfrågorna i figuren är tänkta att bli besvarade genom en litteraturstudie och de vänstra genom experiment. Mer detaljer om detta går det att läsa om i kapitel 2 Metod. Figur 1.2: Visar en trädstruktur över projektets relevanta frågor. 12

1.4 Motivation Då våra applikationer hanterar större och större datamängder samt blir mer och mer komplexa kommer allt mer resurser krävas av vår hårdvara. En stor anledning till att vi får större datamängder har att göra med att mycket mer data idag sparas. Data är väldigt värdefullt, t ex presenteras sökresultat, med hjälp av artificiell intelligens, i en specificerad ordning baserad på tidigare sökresultat i Google. Ett annat exempel är utvecklingen av smarta bilar och smarta städer. Om byte av designteknik möjliggör att man kan utveckla mindre prestandakrävande applikationer, kan företag klara sig på mindre avancerad hårdvara och därmed spara in på kostnaden då minne och minneshantering kostar mycket pengar. Detta skulle då kunna leda till ekonomisk vinning både för samhället och för industrin. Prestandaproblem märks särskilt väl inom spelindustrin då dataspel hanterar mycket data samtidigt. Men allt eftersom våra program hanterar mer och mer data borde det i förlängningen leda till att problemet går att applicera inom alla områden, det vill säga vetenskapen, samhället och industrin. Resultatet av studien kan göra att fler utvecklare får upp ögonen för vad DOD är, samt börjar använda sig av DOD i lämpliga fall. 1.5 Mål Detta projekt har blivit nedbrutet i fyra stycken mål som presenteras i tabell 1.1, nedan. M1 M2 M3 Undersöka och beskriva för- och nackdelar med respektive designteknik genom genomsökning av litteratur/artiklar Implementera respektive designteknik under utvecklingen av en simulering med hjälp av Unity i programmeringsspråket C# Utföra experimentet på de bägge designteknikerna M4 Sammanställa resultaten av experimentet samt respektive designtekniks för- och nackdelar Tabell 1.1: Visar projektets mål. Resultatet av detta projekt är att fördelar och nackdelar med DOD och OOP sammanställs från tidigare undersökningar. Detta bidrar även till att ge större kunskap om DOD då det inte är lika känt som OOP. Projektet kommer även att belysa prestandaskillnader mellan de olika teknikerna, detta genom att mäta ett antal olika parametrar. 13

1.6 Avgränsningar Projektets litteraturundersökning kommer att begränsas genom att artikelsökningar kommer utföras på diva-portalen samt Google Scholar. Endast artiklar skrivna på svenska eller engelska kommer att ingå i undersökningen. Experimentet är begränsat till att utföras på tre olika typer av hårdvara med varierande typer av resurser som presenteras mer utförligt i tabell 2.1 i kapitel 2, Metod. Vidare är experimentet även begränsat till de programmeringsspråk som det är skrivet i samt den spelmotor som används. Mer detaljerad information om detta finns presenterat i kapitel 2 under rubriken Metod. 1.7 Målgrupp Detta problems huvudmålgrupp är utvecklare. Speciellt utvecklare av prestandatunga applikationer som vill fokusera på att skriva kod som minimerar användandet av hårdvarans resurser. En stor målgrupp är spelutvecklarna då det är mycket data som bearbetas på väldigt kort tid i spel och prestandan kan vara direkt avgörande för om dina kunder kommer spela ditt spel eller inte. Men jag personligen tänker också att just en simulering är en utmärkt representation av vad som händer när mycket data ska transformeras på kort tid och i en tid där vi får allt mer data att hantera och applikationer som utnyttjar mycket av hårdvarans resurser. Detta gör att alla utvecklare borde vara intresserade av att producera kod som bearbetas snabbt och effektivt. 1.8 Disposition Resterande kapitel i denna rapport ser ut som följer: Kapitel 2, Metod, presenterar metoderna som valts för att kunna undersöka problemställningar för projektet samt en diskussion om tillförlitlighet och giltighet. Kapitel 3, Implementation, beskriver utvecklingen av simuleringen. Kapitel 4, Resultat, presenterar de resultat som projektet har resulterat i. Detta kapitel består av två huvuddelar, resultatet som de insamlade artiklarna från litteraturundersökningen har visat, samt de resultat som experimentet har uppvisat. Kapitel 5, Analys, diskuterar resultaten och vilka slutsatser som går att dra av dem. Kapitel 6, Diskussion, diskuterar de slutgiltiga resultaten och hur de står sig i förhållande till de resultat som finns publicerade i andra relaterade undersökningar sedan tidigare. Kapitel 7, Sammanfattning, presenterar en sammanfattning om vad projektet har kommit fram till och om resultatet som presenterats varit relevant samt vad som kan göras i framtiden med projektet. 14

2 Teori 2.1 Hårdvaruresurser I detta arbete ska prestandamätningar utföras mellan OOP och DOD och då kan cachningen och cachelinjen visa sig ha stor betydelse. Därför kommer nedanstående text beskriva olika typer av hårdvaruresurser. Datorns primärminne har som uppgift att förse processorn med data. I mitten av 1990-talet märkte man att primärminnet inte kunde förse processorn med data i tillräckligt tillfredsställande hastighet. Processorhastigheten hade utvecklats till att bli så pass effektiv att minnesutvecklingen inte hade hängt med. Detta blev till ett problem då det som styrde systemets prestanda nu var latensen, dvs den tid det tar för data att förflyttas från minnet till processorn. För att komma tillrätta med problemet skapades minneshierarkier bland annat i form av utvecklingen av en cachearkitektur. Syftet med cacheminne är att data som snart ska användas lagras nära processorn för att ge snabbare åtkomst. Latensen kommer att minska på grund av distansminskningen. Ett minnesblock kallas en sida. Sidan med det aktiva minnet kallas för arbetsuppsättning. Det krävs att hela arbetsuppsättningen för en process får plats i cachen. Om sidan är för stor så kommer cachen att kasta den för att frigöra utrymme för nya sidor [2]. Moderna processorer har flera nivåer av cacheminne, vanligtvis L1, L2 och L3. I framtiden kommer troligtvis ännu flera nivåer finnas. L1-cachen ligger i kärnan. Den är tillägnad en specifik kärna och är kärnans arbetsyta. L1- cachen är den minsta av cacharna och variationen i storlek skiljer sig inte så mycket åt mellan olika processorer. Sedan kommer L2-cachen som befinner sig strax utanför kärnan. Finns det flera kärnor på samma chip så delar de vanligtvis på denna cache. L1-cachen hämtar data från L2-cachen som i sin tur förses med data från L3-cachen. L2-cachen är större än L1-cachen men den är mindre än L3-cachen. L3-cachen delas mellan datorns alla processorer och den kan ha segment som är avsedda för specifika processorer eller för grafikprocessorn alternativt andra funktioner. L3-cachen är den cache som skiljer sig mest storleksmässigt mellan olika processorer [2]. Samtidigt som cachar förbättrar prestandan finns även baksidan att de tillför mer komplexitet. Anledningen till detta är att om två kärnor får tillgång till samma minnesområde kan kopior av data finnas i två olika cachar. Om en kärna sedan skriver till sitt minne så kommer data i den andra cachen att vara felaktig och behöva tas bort. Detta är svårt att göra utan att prestandan påverkas negativt. Cachar är något som kommer förändras med tiden. Flera nivåer kan komma och läggas till och vissa kanske tas bort samt att vilka nivåer som delas av kärnor också kan förändras i takt med utvecklingen [2]. Cachelinje kallas enheten där dataöverföringen sker mellan cachen och minnet. Vanligtvis är cachelinjen 64 bytes. Processorn skriver eller läser alltid in en hel cachelinje dessa kan läsas in radvis eller kolumnvis, varav 15

radvis inläsning är mer effektiv då kolumnvis resulterar i byte av cachelinje [8]. 2.2 Objektorienterad programmering (OOP) Objektorienterad programmering (OOP) är den mest använda designtekniken idag [10] och har från början sitt ursprung från Norwegian Computing Center i Oslo, på 1960-talet från programmeringsspråket Simula I som var avsett för att skriva simuleringsprogram. Det verkliga genombrottet för OOP kom dock med programmeringsspråket Smalltalk som lanserades först 1980 och räknas som det första renodlade objektorienterade språket [11], [12]. Efter det spred sig OOP till en mängd andra programmeringsspråk. Inom industrin så räknas dock C++ som det språk som har haft störst inflytande på användningen av OOP [11]. I en artikel av Noel Llopis beskrivs vissa svagheter med OOP. Artikeln som bygger på hans egna erfarenheter av spelutveckling med C++ stöds dessvärre inte upp med några konkreta mätvärden. Llopis menar att OOP på dagens hårdvara, bestående av minneshierarkier, kan leda till problem och dålig prestanda. Detta då dålig minnesåtkomst och cachemissar har konstaterats. Samtidigt som försök på att parallellisera koden endast har lett till en marginell prestandaökning. Parallellisering av OOP-kod beskrivs även som en svårighet. Detta då man samtidigt måste förhindra samtidig åtkomst av data från flera trådar och att vissa trådar måste vänta på att andra trådar ska slutföras. Enligt Llopis är det ideala datat förpackat i ett format som gör det möjligt att använda med minsta möjliga ansträngning. Det vill säga stora block av sammanhängande, homogen data, som kan bearbetas sekventiellt. Data i OOP är strukturerat genom en lista som lagrar pekare till objekt, som inte sällan är en lista med heterogen data, i minnet. OOP använder sig av klasser som ärver varandra vilket leder till hierarkier med utspridd tillhörande data [3]. 2.3 Dataorienterad design (DOD) Dataorienterad design (DOD) namngavs så sent som 2009 i en artikel av Noel Llopis men har funnits i olika former i årtionden [13]. Enligt Llopis fokuserar DOD, till skillnad från OOP, på själva datat, hur det är upplagt i minnet samt hur det kommer läsas och bearbetas. Objekten delas upp i mindre delar som kallas komponenter. Dessa komponenter innehåller bara data som hör ihop. Sedan lagras dessa komponenter i en lista som innehåller homogen data. Detta leder till block av homogen data som kan bearbetas sekventiellt vilket resulterar i bra cachning och bra prestanda [3]. F igur 1.1 ger en bild över hur det kan se ut. Figuren är hämtad från Llopis artikel skriven utifrån spelkontext med användning av C++. 16

Figur 2.1: Visar OOP:s heterogena fördelning av data vs DOD:s homogena fördelning av data [3]. Det är viktigt att skilja på begreppen data orienterad design och data driven design. Då data orienterad design handlar om hur data är organiserad för att effektivisera processningen. Medan data driven design istället handlar om att låta data bestämma applikationens beteende istället för att detta skrivs i kod. Även om applikationen är data driven betyder det alltså inte att den är data orienterad den skulle lika gärna kunna vara objektorienterad [3, 14]. 2.4 Prestandamätning Vid mätning av prestanda kan man mäta bildrutor per sekund (FPS) som representerar hur många nya bilder som skapas per sekund. Detta styrs av grafikprocessorn tillsammans med hårdvaran och mjukvaran som körs. Vid låg FPS så upplever man att bilden blir hackig ( laggar ) eller rörliga föremål blir ryckiga. 24 FPS uppfattas oftast av det mänskliga ögat som okej när det handlar om en animation eller ett videoklipp. Inom spelvärlden brukar målet sättas på 60 FPS även om 30 FPS även också betraktas som acceptabel t [15]. Minnesanvändning kan mätas då hög användning gör att hårdvarans prestanda sjunker då det tar längre tid för datat att nå processorn [16]. 17

3 Metod Detta projekt kommer att använda sig av två olika metoder för att besvara frågeställningen. Metoderna som kommer att användas i denna studie är: Systematisk litteraturundersökning, som är en sekundär studie där inga nya data tas fram utan data från tidigare forskning istället bearbetas [17]. Detta ansågs som en väl lämpad metod för utvärdering av för- och nackdelar då det är något som det säkerligen finns mycket information om redan. Genom att utföra en litteraturundersökning sammanställs information från forskare och experter. Ett alternativ till detta hade kunnat vara att utföra enkätundersökningar. Detta ansågs dock vara något som skulle vara mer tidskrävande och ge ett sämre utfall, i synnerhet när det kommer till DOD som är relativt okänt. Det hade därför varit svårt att hitta målgruppen som använder DOD. Kontrollerade experiment, som innebär att ett experiment med mätning av kvantitativ data utförs i kontrollerad miljö för att visa på skillnader eller likheter mellan påståenden [18]. Denna metod valdes då även kvantitativ data skulle tas fram för att visa på eventuella skillnader i prestanda mellan de olika designteknikerna. När denna metod valdes fanns det inga alternativ. Det går att tänka att man även i detta fall skulle kunnat använda sig av en litteraturstudie. Men när inga sådana studier fanns att tillgå så var det aldrig en rimlig möjlighet. 3.1 Systematisk litteraturundersökning Vid litteratursökningen kommer Google Scholar och diva-portalen att användas. Google Scholar användes då det är öppet för alla och innehåller forskningsmaterial och akademiska artiklar. Diva-portalen är även den öppen för alla och innehåller en mängd forskningsmaterial. För att möjliggöra att få så många träffar som möjligt togs söktermerna fram genom att använda Google och söka på synonyms pros and cons. De söktermer detta resulterade i och som kommer att användas är: Pros and cons Advantages and disadvantages Assets and liabilities For and against Gains and losses Opportunities and obstacles Strengths and weakness Positives and negatives Benefits and limitations Dessa ord kommer kombineras med Object oriented design/programming och Data oriented design/programming. Förutom dessa söktermer så kommer även sökningar utföras på Object oriented design/programming versus Data 18

oriented design/programming. Dessa sökningar kommer även att utföras på Google. Detta för att kunna få fram ännu fler intressanta träffar. Den litteratur som kommer inkluderas i denna studie är litteratur från 2009 och framåt. Äldre litteratur kommer exkluderas då de nya är mer relevant. Detta gäller då kanske speciellt när det kommer till DOD som ändå kan anses som en relativt ny teknik i sammanhanget. Vidare så kommer endast svenska och engelska artiklar att inkluderas i detta projekt på grund av språkbegränsningar. Den data som kommer extraheras från studierna är för- och nackdelarna med de respektive teknikerna. Detta för att kunna svara på frågorna från frågeställningen vilka för- och nackdelar finns med de respektive teknikerna? samt ökar DOD komplexiteten på koden?. Dessa resultat kommer sedan att summeras, i en tabell, för att se hur många av artiklarna som tar upp samma för- och nackdelar. De för- och nackdelar som endast nämns i enstaka artiklar kommer inte behandlas i detta arbete. Detta då de inte anses lika tillförlitliga. 3.2 Kontrollerade experiment Experimentet ska jämföra två simuleringar. En simulering med kod organiserad utifrån OOP samt en med kod organiserad utifrån DOD. Mätningar skall utföras för att se om det föreligger några prestandaskillnader mellan de olika versionerna. Detta experiment genomförs för att kunna svara på frågorna från frågeställningen är DOD ett bättre designval än OOP vid prestandakrävande applikationer?, hur stor blir prestandaskillnaderna mellan de olika designteknikerna? och finns det möjlighet att utveckla mindre prestandakrävande program endast genom att ändra designteknik?. Vid experimentet kommer de beroende variablerna vara FPS, minnesanvändning samt grafikprocessor- och processorbelastning. Mätningarna kommer att utföras med hjälp utav Unitys inbyggda profileringsverktyg [19]. Dessa mätvariabler finns tillgängliga i profileringsverktyget och anses lämpliga att utvärdera. Detta då FPS är det mest frekventa sätt att mäta prestanda på idag även om hur mycket tid processorn lägger ner på varje frame ger en rättvisare bild av prestandan [19]. Därav kommer bägge dessa att mätas med mer exakta värden av processoranvändningen som kommer mätas i ms. FPS styrs även av grafikprocessorn tillsammans med andra komponenter så därav mäts även användningen av denna. Minnesanvändning mäts då en hög sådan kan göra att det tar längre tid för data att nå processorn [16]. Simuleringen kommer att kodas i C# och utvecklas i Unity. För att få simuleringen att bli prestandakrävande kommer många rörliga objekt alternativt entiteter att skapas. Tanken är att antalet rörliga objekten/entiteterna (oberoende variabler) ska mätas på tre olika nivåer. Dessa nivåer ska bestämmas med hjälp av OOP simuleringen. Antalet objekt/entiteter ökas och sätts beroende på beetendet av simuleringen i miljö 19

2. Nivåerna tas fram enligt följande kriterier: Nivå 1: Normalt antal rörliga objekt dvs ingen påtaglig visuell prestandaproblematik med OOP simuleringen. Nivå 2: Visuell påverkan på prestandan med OOP simuleringen. Nivå 3: Ännu fler rörliga objekt än nivå 2. Mätningen kommer att ske i de tre olika miljöer som finns presenterade i tabell 3.1, nedan. Resurser Miljö 1 Miljö 2 Miljö 3 Processor Intel Core i5-4200u Intel Core i7-4770k Intel Core i7-8700k Processorhastighet 1,60 GHz 3,50 GHz 3,70 GHz Processorkärnor 2 4 6 L1 cache 128 KB 256 KB 384 KB L2 cache 512 KB 1 MB 1,5 MB L3 cache 3 MB 8 MB 12 MB Minne DDR3 DDR3 DDR4 Minneshastighet 1600 MHz 1600 MHz 3600 MHz Minnesmängd 7,89 GB 15,6 GB 32,0 GB Grafikprocessor Intel HD Graphics 4400 GeForce GTX 780 GeForce GTX 1080 Grafikminne 1792 MB 4 GB 11 GB Operativsystem Windows 8.1 64-bitars Ubuntu 18.04.4 LTS 64-bitars Windows 10 64-bitars Tabell 3.1: Visar de tre olika miljöerna som experimentet ska utföras i. Urvalet av de olika miljöerna har sin grund i de olika typer av hårdvara som jag har hemma. Men man kan samtidigt tänka sig att det är en någorlund väl representation på vad populationen kan tänkas använda som hemdatorer. 20

Miljö 1 är en vanlig original laptop som erbjuder de svagaste resurserna och miljö 3 de främsta, medan miljö 2 ligger mitt emellan dessa. Miljö 2 och 3 är stationära datorer med grafikkort anpassade för förstärkt spelupplevelse. 3.3 Tillförlitlighet och validitet Hur man skriver koden kommer med högsta sannolikhet påverka hur den bearbetas. Man kan mycket väl tänka sig att skillnaden mellan OOP och DOD blir mindre om den som skriver koden har lång erfarenhet av OOP och parallellisering av kod och samtidigt ingen tidigare erfarenhet av DOD. I mitt fall har jag har lite erfarenhet av OOP medan DOD är helt nytt för mig. Samtidigt är programmeringsspråket C# och Unity också något som är helt nytt för mig därav kanske mina mätningar mellan OOP och DOD kommer att skilja sig åt mer. Det är därför viktigt att vara medveten om detta när man tolkar resultatet. Dels att tidigare erfarenhet av OOP och DOD påverkar men även att dessa mätningar gäller för Unity. Om någon annan typ av spelmotor eller ramverk hade använts hade resultaten kunnat se annorlunda ut. Detta är något som alltså påverkar den externa validiteten av experimentet, d v s hur bra detta resultat skulle hålla sig i närvaro av andra variabler. Variablerna är i detta fall programmeraren, C#, tidigare erfarenheter och Unity. Det går även att tänka sig att resultaten påverkas av omedvetna subjektiva formuleringar i språket. Dock är detta inget som påverkar de konkreta mätvärdena. Mätningarna kommer högst sannolikt att påverkas även av vilken hårdvara man använder sig av. Detta är ett exempel på en extern validitet. Därav kan man säga att den externa validiteten av mätningarna stärks av att de kommer att utföras på tre olika typer av hårdvara. När man utför mätningarna så kommer även själva utförandet att ta resurser från datorn. Detta är dock något som kommer påverka både mätningen av OOP-implementeringen och DOD-implementeringen i samma utsträckning. Vilket därför inte borde påverka själva jämförandet mellan de olika implementeringarna som utförs inom samma miljö. När mätningarna utförs så kommer även de program som inte behöver vara igång att stängas ner för att frigöra hårdvaruresurser. Detta är något som stärker den externa validiteten av experimentet. För att stärka den interna validiteten, d v s att resultatet inte ska kunna manipuleras, kommer mätningarna ske flera gånger på samma nivå inom samma miljö. Att dessa mätningar utförs flera gånger är också ett sätt att se hur konsekvent resultatet av mätningarna är, d v s hur tillförlitligt resultatet är. Detta stärker alltså tillförlitligheten av resultatet. Att resultatet är tillförlitligt innebär att resultatet är konsekvent under samma omständigheter. 21

3.4 Etiska överväganden Projektet samlar dels in data som redan finns publicerade i form av en litteraturundersökning och samlar dels in ny data i form av ett experiment, där inga personliga eller känsliga data kommer att behandlas. Litteraturundersökningen är utförd enligt ovanstående beskrivning vilket gör det möjligt att återupprepa den. Data från experimentet är insamlad genom två konstruerade experiment utan några övriga deltagares inblandning. 22

4 Implementation 4.1 Beskrivning av simuleringen Simuleringen som kommer att byggas i Unity (v.2019.3.11.f1) ska för att testa prestandan bestå av många rörliga objekt (OOP) eller entiteter (DOD). De rörliga objekten alternativt entiteterna består av kuber. Kuberna bygger tillsammans upp en struktur bestående av ett varierande antal kuber. De olika antalet kuber representeras av nivå 1, 2 och 3. Användaren kan välja att antingen sätta variabeln numberofcubes i inspektorn som kommer bygga upp en struktur bestående av det inmatade kubantalet med ett fast antal kuber som varje lager består av. Alternativt så kan användaren sätta antalet kuber i variablerna width, deep och height och då kommer det byggas upp en struktur baserat på dessa värden. Om det finns värden satta i width, deep och height så kommer strukturen baseras på dessa istället för numberofcubes. Om man vill sätta exakt antal kuber bör man därför alltid se till att width, deep eller height är satt till 0. 3 sekunder efter den att kubstrukturen byggts upp kommer en explosion att inträffa som får alla kuber i strukturen att sättas i rörelse. Detta sker genom att ett sfär objekt/entitet placeras i mitten av strukturen i det nedersta lagret närmast marken. Denna sfär kommer att öka sin radie för varje frame. När sfären nått variabeln maxwidths värde har explosionen uppnått sin fulla kraft och därmed kommer sfären att raderas. Variabeln maxwidth kommer alltid ha samma värde som variabeln width. Kuberna i strukturen kommer kontinuerligt att byta färg varje frame ända tills explosionen nått sin fulla kraft. Denna uppbyggnad med varierande antal kuber kommer resultera i att processorn behöver göra beräkningar av respektive kubs x-, y- och z-värden som hela tiden kommer förändras då kuberna befinner sig i rörelse och är påverkade av gravitationskraften. Ju fler rörliga kuber desto fler uträkningar kommer ske och desto tyngre blir det för processorn. Bytet av färg som sker varje frame på kuberna kommer resultera i att kuberna blinkar. Dessa blinkningar kommer att underlätta för ögat att se när simuleringen laggar, d v s tappar frames. Då profileringsverktyget endast sparar 600 frames så kommer applikationen att avslutas efter 600 frame har uppnåtts. Explosionen kommer att ske inom dessa frames så i slutet av simuleringen kommer kuberna ligga stilla varav mätningen inte längre är lika relevant. Nedan finns bilder presenterade tagna från utvecklingsprocessen av simuleringen. Bilderna är tagna från inspektorn. 23

Figur 4.1: Visar simuleringens inledande del då kubstrukturen har byggts upp. 24

Figur 4.2: Visar simuleringens explosion då alla kuber sätts i rörelse. Simuleringarna kommer sedan att köras i tre olika miljöer, på tre olika nivåer, där mätningarna kommer att utföras. Tabell 4.1 visar en översiktsbild av detta. 25

Tabell 4.1: Översikt över de 18 experiment som kommer att utföras. OOP/M1/N1 betyder simulering i OOP i miljö 1 på nivå 1. 26

4.1.1 OOP implementeringen I OOP implementeringen representeras kuberna av spelobjekt. Dessa fungerar som containrar för komponenter som ger objektet dess olika funktionaliteter. För att renderas upp som en kub så sätts komponenterna Mesh Filter och Mesh Renderer till kuben. För att kuben ska bete sig rent fysiskt som en kub så läggs komponenten Box Collider till objekt et [20]. För att objektet ska påverkas av gravitationen så läggs komponenten Rigidbody til l [21]. Klassdiagrammet, fig 4.3, visar de olika klasserna som samverkar med varandra i implementeringen. Alla dessa klasser kommer även att ärva från Unitys basklass MonoBehaviour. Denna klass ger tillgång till funktioner och events för standardskript som använder sig av spelobjek t [22]. Figur 4.3: Visar de fyra klasserna som samverkar med varandra. 27

4.1.2 DOD/DOTS implementeringen För att kunna använda sig av DOTS och ECS installerades följande tilläggspaket med hjälp av pakethanteraren: Entities (preview) v 0.9.1, Hybrid Renderer (preview) v. 0.4.2 och Unity Physics (preview) v 0.3.2. I DOD implementeringen representeras kuberna av entiteter. Entiteterna håller komponenter som i sin tur håller data. Samma kub spelobjekt som instansieras i OOP-versionen används även i denna implementering men här konverteras spelobjektet till en entitet innan den instansieras. Vid konverteringen kommer Mesh Filter och Mesh Renderer konverteras till komponenten RenderMesh [23] Box Collider till PhysicsShape samt Rigidbody till PhysicsBody [24]. Klassdiagrammet, fig 4.4, visar de fyra komponenterna och deras fyra system. Då komponenter är structs som endast kan hålla värdetyper och Material och Mesh är referenstyper så finns även två klasser som ärver från MonoBehaviour med i simuleringen. Detta medför att simuleringen inte är en renodlad DOD simulering. MonoBehaviour ärver i sin tur från klassen Behaviour som ärver från Component som i sin tur ärver från Object. Detta bygger upp en hierarki av klasser som ärver från varandra. Därav finns det även ett begränsat inslag av OOP även i denna simulering [25-28]. Figur 4.4: Visar de fyra komponenterna och dess fyra system som samverkar med varandra. Två klasser som ärver från MonoBehaviour är även med. 28

4.1.3 Objektstruktur Om man jämför de två klassdiagrammen så ser man att alla klasser i OOP-implementeringen ärver från MonoBehaviour. Detta betyder att alla dessa klasser har denna arvshierarki som är fyra klasser djup, det vill säga MonoBehaviour, Behaviour, Component och Object. Tittar man på klassdiagrammet över DOD-implementeringen är det bara två klasser som har denna arvshierarki. Resterande klasser implementerar antingen interfacet IComponentData eller klassen SystemBase, beroende på om det är en komponent eller ett system. 4.2 Tidskomplexitet och minneskomplexitet Granskar man min kod borde tidskomplexiteten vara linjär, O(n). Dock beror detta även på hur Unitys kod är skriven. Tittar man i figur 5.4 och 5.9, som visar processoranvändningens medelvärde i miljö 1 och 2, visar de att mätpunkterna lägger sig på linje, vilket även det indikerar på att tidskomplexiteten skulle vara linjär. Det syns även att DOD-grafen har ett lägre k-värde än OOP-grafen det vill säga DOD-linjens lutning är mindre än OOP-linjens. Troligtvis är både DODs och OOPs tidskomplexitet linjär. För att få en säkrare uppfattning om detta skulle dock antalet mätnivåer i experimentet behöva utökas ytterligare. Minneskomplexiteten som visas av figur 5.5 och figur 5.14 visar att OOP-grafens punkter lägger sig på linje. Detta tyder på att minneskomplexiteten för OOP är linjär medan DOD-grafens k-värde är 0, d v s minneskomplexiteten för DOD ökar inte med antalet kuber. 29

5 Resultat I detta kapitel presenteras resultatet av litteraturundersökning samt de mätvärden som uppmätts med hjälp av profileringsverktyget som finns inbyggt i Unity. För att kunna få ut ett medelvärde av antalet ms som processorn spenderar på varje frame har även paketet Profiler Analyzer v. 1.0.1 laddats ner med hjälp av pakethanteraren. 5.1 Systematisk litteraturundersökning Artiklarna som används i litteraturundersökningen baserar sig på sökningar utförda i Google då sökningarna i Google Scholar och diva-portalen inte resulterade i några relevanta träffar. OOP fördel Antal artiklar / Totalt antal artiklar Artikel källa Återanvändning av kod (arv) 9 / 17 [29-37] Lätt att underhålla koden 8 / 17 [29-30], [33-38] Säkerhet (inkapsling) 6 / 17 [29-32], [35-36] Objekten som används reflekterar den mänskliga verkligheten 6 / 17 [29], [31], [33], [35], [39-40] Parallell utveckling 4 / 17 [29], [33], [35-36] Sänker programmeringskostnaden 2 / 17 [37], [41] Bra för GUI-programmering 2 / 17 [3], [41] Tabell 5.1: Visar de framkomna fördelarna med OOP. I tabell 5.1 presenteras de fördelar som framkom vid användning av OOP. De fördelar samt nackdelar som endast uppkom i en enstaka artikel har inte tagits med i undersökningen då undersökningen är utförd på grå litteratur som anses ha mindre trovärdighet. Då det var lättare att hitta information om OOP än DOD så baserar sig OOP underlaget på 17 artiklar [3], [29-44] medan DOD endast baserar sig på 4 stycken artiklar [3], [39], [42], [45]. De fördelar som är vanligast förekommande i artiklarna är att OOP gör att det är lätt att underhålla koden, återanvändning av kod vilket ofta sker genom arv, säkerhet i form av inkapsling samt att objekten som används reflekterar den mänskliga verkligheten. En anledning till att OOP beskrivs som mer prestandakrävande är att OOP inte utnyttjar cachen lika effektivt som DOD. Detta beror bland annat på att objekten oftast är stora och innehåller mycket data. Är man intresserad av specifik data, som t ex endast en variabel, från ett objekt så kommer man 30

ladda in all data från detta objekt. Detta resulterar i onödig data i cachen vilket leder till ineffektiv cachning [40, 42]. Återanvändning av kod i form av arv blir då något som även kan ses som negativt då det också är en bidragande faktor till att OOP blir än mer prestandakrävande i och med att även klasserna som ärvs läses in i cachen och därmed adderar ännu mer onödig data [3], [43-44]. Just prestandakrävande är också det som nämns som den vanligaste nackdelen med OOP vilket går att se i tabell 5.2. OOP nackdel Antal artiklar / Totalt antal artiklar Prestandakrävande 11 / 17 Koden har en tendens att bli rörig och kräver därför ordentlig planering samt kunskap 6 / 17 Tabell 5.2: Visar de framkomna nackdelarna med OOP. Artikel källa [3], [29-31], [34-37], [39], [41], [43], [29-31], [33], [35-36] OOP-program är mycket större än andra program 4 / 17 [30], [35-37] Parallellisera koden är komplext 3 / 17 [3], [39], [44] Är inte en lämplig lösning för alla typer av problem 2 / 17 [3], [37] OOP-koden nämns som lätt att underhålla dock menar vissa på att det krävs ordentlig planering och kunskap för att undvika att den stora kodbasen blir rörig. Något som också nämns är att OOP-koden upplevs som komplex att parallellisera. Detta tas också upp som motpol i DOD som anses lättare att parallellisera i jämförelse med OOP, se tabell 5.3. Detta motiveras med att risken med att processorn försöker få åtkomst till samma data samtidigt blir större med OOP än med DOD. Detta då DOD är skrivet med fokus på hur data generellt bearbetas och är därmed grupperad med liknande data [3, 39]. 31

DOD fördel Antal artiklar / Totalt antal artiklar Artikel källa Cachevänligare kod som leder till färre cachemissar 3 / 4 [3], [39], [42] Lättare att parallellisera i jämförelse med OOP 2 / 4 [3], [39] Lätt att förstå och underhålla koden 2 / 4 [3], [45] Lätt att testa 2 / 4 [3], [45] Tabell 5.3: Visar de framkomna fördelarna med DOD. I tabell 5.3 går det att se att DOD ses som en cachevänligare kod än OOP som leder till färre cachemissar. DOD nackdel Antal artiklar / Totalt antal artiklar Artikel källa Tar tid att lära sig och kräver en del övning 2 / 4 [3], [45] Tabell 5.4: Visar de framkomna nackdelarna med DOD. I Mike Actons föreläsning säger han: Programmerarens jobb är inte att skriva kod. Programmerarens jobb är att lösa data transformeringsproblem. Koden är verktyget som vi använder för att kunna lösa problemet. Han menar på att i OOP så ligger mycket fokus på just koden medan DOD istället lägger fokuset på just data och hur det bearbetas [46]. 5.2 Kontrollerade experiment För att kunna utföra experimentet togs först tre mätnivåer fram med ett varierande antal kuber. Sedan utfördes mätningarna på alla tre nivåer i de tre olika miljöerna som finns presenterade i tabell 3.1 under rubriken metod. 5.2.1 Framtagning av mätnivåer Mätnivåerna bestående av nivå 1, 2 och 3 togs fram genom att OOP-simuleringen kördes i miljö 2, den miljön med medel begränsade resurser. Nivåerna som sattes visas i tabell 5.5 nedan. 32

Nivåer Antal kuber Nivå 1 3000 Nivå 2 5000 Nivå 3 7000 Tabell 5.5: Visar de tre olika nivåerna framtagna i miljö 2 med hjälp av OOP-simuleringen. Nivåerna bestämdes genom att development builds skapades med olika antal kuber. Först togs nivå 2 fram då simuleringen laggar vid körningens början men sedan fortsätter utan lagg. Nivå 1 sattes vid 3000 kuber då simuleringen inte visade något påtagligt lagg. Nivå 3 sattes vid 7000 kuber då simuleringen visade mycket lagg under hela körningen. 5.2.2 Mätresultat För att mätvärdena skulle bli så rättvisa som möjligt stängdes onödiga bakgrundsprocesser ner. Innan själva mätresultatet sparades på respektive nivåer kördes simuleringen 3 gånger för att se att värdena mellan varje gång inte visade för stora avvikelser. Efter detta sparades 5 stycken filer med mätningar på respektive nivå. Väntetiden mellan varje mätning var 1 minut. Detta tidsmått sattes för att varje mätning skulle gå så systematiskt till som möjligt. På dessa fem värden baserar sig medelvärdet. Om någon/några av mätvärdena på samma nivå stack ut för mycket uteslöts det ur medelvärdet då det kan tänkas vara felaktigt. Denna skillnad kan tänkas bero på att datorn kör bakgrundsprocesser. Profileringsverktyget som användes vid mätningarna hade profilering över processor och minne. Från processor profileringen presenteras bilder med grafer över hur många ms processorn spenderar på varje frame. För att se exakt hur många ms processorn spenderar på en specifik frame måste man markera den i grafen. Då ett medelvärde är intressantare så valdes istället att ladda in filen från profilerings verktyget till profiler analyzer som genererar medeltiden som processorn spenderar på varje frame under hela körningen. Grafen är även indelad i olika färger. Dessa färger representerar vad det är som processorn lägger sin tid på. Generellt för alla mätningar är att OOP-mätningarna domineras av orange vilket står för tiden som simuleringen spenderar på fysik motorn (eng. physics engine) Man kan även se på de bilder där ovansidan av grafen syns att grafen är mörkblå i början av mätningarna. Den mörkblå färgen representerar tiden som läggs på att köra scripten. Den ljusgröna färgen allra högst upp i grafen, som endast tar upp en liten del av grafen, representerar grafik renderingen. DOD-mätningarnas 33

grafer är mestadels mörkblå vilket visar att simuleringen spenderar den mesta delen av tiden på att köra scripten. En liten del av grafen högst upp är även ljusgrön vilket visar tiden som läggs på grafik renderingen [47]. Medelvärdet av allokerat RAM-minne lästes av från parametern total system minnesanvändning i minnes profileringen. Denna parameter presenterar den totala storleken på minnet som simuleringen använder enligt operativsystemet [48]. 5.2.2.1 Miljö 1 När man körde simuleringen på nivå 1 med 3000 rörliga kuber, dvs experiment OOP/M1/N1, kunde man se att OOP-versionen laggade påtagligt. Detta märktes både i långsamma blinkningar av kuberna samt ryckighet i bilden då kuberna rörde sig. I slutet laggar den mindre men lagget förekom ändå under hela körningen. Även i DOD-versionen, experiment DOD/M1/N1, så blinkade kuberna långsammare samt att kuberna rörde sig ryckigt. Detta märks dock endast i början av simuleringen. Figur 5.1: Visar diagram över hur många ms processorn spenderar på varje frame på nivå 1, M1/N1. Det övre diagrammet visar OOP-mätningen och de nedre DOD-mätningen. Vid körningen på nivå 2 med 5000 rörliga kuber, dvs experiment OOP/M1/N2, såg man att OOP-versionen laggar mycket under hela körningen. Detta märks genom att kuberna blinkar ännu långsammare än de gjorde i nivå 1 samt att kuberna är ännu mer ryckiga när de rör sig. Det märks även att simuleringen kör längre tid. Detta då den avslutas efter 600 frames. Även DOD-versionen, experiment DOD/M1/N2, laggar under hela körningen dock mindre än i OOP-versionen. 34

Figur 5.2: Visar diagram över hur många ms processorn spenderar på varje frame på nivå 2, M1/N2. Det övre diagrammet visar OOP-mätningen och de nedre DOD-mätningen. På nivå 3 med 7000 rörliga kuber, dvs experiment OOP/M1/N3, såg man att OOP-versionen laggar extremt mycket under hela körningen. Detta märks genom att kuberna inte blinkar alls när kubstrukturen rasar och kuberna är ännu mer ryckiga när de rör sig. Först när kuberna ligger på marken så börjar de blinka. Den absolut största skillnaden är dock hur länge simuleringen körs för att köra sina 600 frames. OOP-Simuleringen som endast körde i 30 sekunder på nivå 1 i denna miljö, kör på denna nivå i 5 min och 48 sekunder. Även DOD-versionen, experiment DOD/M1/N3, visade tydlig laggning under hela körningens gång. Både med långsamma blinkningar, ännu långsammare än föregående DOD-nivå samt ännu mer ryckiga kuber. I DOD-versionen blinkar dock kuberna samtidigt som kubstrukturen rasar. DOD-versionen tar dock endast 39 sekunder att köra. Vilket betyder att OOP-versionen tydligt tappar betydligt fler frames än DOD-versionen gör. Figur 5.3: Visar diagram över hur många ms processorn spenderar på varje frame på nivå 3, M1/N3. Det övre diagrammet visar OOP-mätningen och de nedre DOD-mätningen. I tabell 5.6 presenteras det exakta medelvärdet från alla fem mätningar på respektive nivå. Detta medelvärde är den tid, i ms, som processorn lägger under en frame. Dessa fem medelvärden används för att räkna ut ett medelvärde av hur många ms som processorn spenderar på en frame. Detta 35

finns uppritat i linjediagrammet som presenteras i figur 5.4. Tabell 5.6: Visar OOP- och DOD-mätningen över processoranvändningen. Mätvärdet visar medelvärdet på hur många ms processorn måste jobba per frame. Figur 5.4: Visar ett linjediagram över medelvärden från tabell 5.6. Mätningen av medelvärdet på hur mycket RAM-minne som används vid körningen av applikationen på de tre olika nivåerna finns presenterade i tabell 5.6. De finns även presenterade i ett linjediagram i figur 5.4. Tabell 5.7: Visar OOP- och DOD-mätningen över minnesanvändningen. 36

Mätvärdet visar medelvärdet av minnesanvändningen i GB. Figur 5.5: Visar ett linjediagram över medelvärden från tabell 5.7. 5.2.2.2 Miljö 2 Vid körningen av simuleringen på nivå 1 med 3000 rörliga kuber, dvs experiment OOP/M2/N1, kunde man se att OOP-versionen har lite lagg då kuberna blinkar något långsammare vid simuleringens start. Detta är dock något som ögat inte hade registrerat om man inte hade haft blinkningarna. DOD-versionen, experiment DOD/M2/N1, visade inget lagg. Figur 5.6: Visar diagram över hur många ms processorn spenderar på varje frame på nivå 1, M2/N1. Det övre diagrammet visar OOP-mätningen och de nedre DOD-mätningen. Under körningen av av simuleringen på nivå 2 med 5000 rörliga kuber, dvs experiment OOP/M2/N2, kunde man se att OOP-versionen laggar påtagligt vid simuleringens start. Detta märks både genom att blinkningarna går långsammare samt att kuberna rörde sig ryckigt i början då kubbyggnaden 37

faller. I DOD-versionen, experiment DOD/M2/N2, förekom inget synligt lagg. Figur 5.7: Visar diagram över hur många ms processorn spenderar på varje frame på nivå 2, M2/N2. Det övre diagrammet visar OOP-mätningen och de nedre DOD-mätningen. På nivå 3 med 7000 rörliga kuber, dvs experiment OOP/M2/N3, kunde man se att OOP-versionen laggar påtagligt under hela simuleringens körning. Detta märktes både i långsamma blinkningar av kuberna samt ryckighet i bilden då kuberna rörde sig. Eftersom simuleringen är skriven så att den avslutas efter 600 frames så blev det också en tydlig skillnad i hur länge simuleringen körs. Det är först på denna nivå som man märker av att DOD-versionen, experiment DOD/M2/N3, laggar. Detta märks dock bara i början av simuleringen då blinkningarna går långsammare samt att kuberna rör sig lite ryckigt. Den liknar lite OOP-versionens beteende i nivå 2. Om än är DOD-versionen på denna nivå något effektivare. Detta går även att se av mätningarna om man jämför dessa två grafer (dvs figur 5.7:s övre del med figur 5.8:s nedre del). Figur 5.8: Visar diagram över hur många ms processorn spenderar på varje frame på nivå 3, M2/N3. Det övre diagrammet visar OOP-mätningen och de nedre DOD-mätningen. Det exakta medelvärdet från alla fem mätningar på respektive nivå visas i tabell 5.8. Detta medelvärde är den tid, i ms, som processorn lägger under en 38

frame. Dessa fem medelvärden används för att räkna ut ett medelvärde av hur många ms som processorn spenderar på en frame. Detta finns uppritat i linjediagrammet som presenteras i figur 5.9. Tabell 5.8: Visar OOP- och DOD-mätningen över processoranvändningen. Mätvärdet visar medelvärdet på hur många ms processorn måste jobba per frame. Figur 5.9: Visar ett linjediagram över medelvärden från tabell 5.8. Mätningen av medelvärdet på hur mycket RAM-minne som används vid körningen av applikationen på de tre olika nivåerna finns presenterade i tabell 5.9. Dessvärre ser man att medelvärdet av hur mycket RAM som används (GB) ökar för varje körning. Då denna mätning inte är tillförlitlig så kommer ingen tid läggas på att konstruera ett linjediagram. Dessa värden presenteras här i denna tabell men kommer dessvärre inte kunna användas vidare då de uppenbart är felaktiga. Denna mätning utfördes på Ubuntu 18.04 LTS med Gnome shell 3.28.2. Dessvärre är det en känd bugg att denna version samt senare versioner av Gnome har minnesläckage [49]. Detta är troligtvis 39

orsaken till de felaktiga mätvärdena. Då tiden för detta examensarbete är begränsad går det dessvärre inte att lägga mer energi på detta. Tabell 5.9: Visar OOP- och DOD-mätningen över minnesanvändningen. Mätvärdet visar medelvärdet av minnesanvändningen i GB. 5.2.2.3 Miljö 3 Vid körningen av simuleringen på nivå 1 med 3000 rörliga kuber, dvs experiment OOP/M3/N1, syntes inget lagg i någon av de båda versionerna. Figur 5.10: Visar diagram över hur många ms processorn spenderar på varje frame på nivå 1, M3/N1. Det övre diagrammet visar OOP-mätningen och de nedre DOD-mätningen. Under körningen på nivå 2 med 5000 rörliga kuber, dvs experiment OOP/M3/N2, kunde man se att OOP-versionen laggade lite i början av körningen. Detta visade sig dock endast i att kuberna blinkade något långsammare i simuleringens början. I DOD-versionen, experiment DOD/M3/N2, syntes inget lagg. 40

Figur 5.11: Visar diagram över hur många ms processorn spenderar på varje frame på nivå 2, M3/N2. Det övre diagrammet visar OOP-mätningen och de nedre DOD-mätningen. Körningen av OOP-versionen på nivå 3, med 7000 rörliga kuber, dvs experiment OOP/M3/N3, visade tydlig lagg i början av körningen. Detta visade sig både genom att kuberna blinkade långsammare samt att de rörde sig ryckigare. DOD-versionen, experiment DOD/M3/N3, visade dock inget synligt lagg. Figur 5.12: Visar diagram över hur många ms processorn spenderar på varje frame på nivå 3, M3/N3. Det övre diagrammet visar OOP-mätningen och de nedre DOD-mätningen. Det exakta medelvärdet från alla fem mätningar på respektive nivå finns presenterade i tabell 5.10. Medelvärdet från dessa mätvärden finns presenterade i linjediagrammet, figur 5.13. 41

Tabell 5.10: Visar OOP- och DOD-mätningen över processoranvändningen. Mätvärdet visar medelvärdet på hur många ms processorn måste jobba per frame. Figur 5.13: Visar ett linjediagram över medelvärden från tabell 5.10. Tabell 5.11 presenterar mätningen av medelvärdet på hur mycket RAM-minne som används vid körningen av applikationen på respektive nivåerna. De finns även presenterade i ett linjediagram i figur 5.14. Tabell 5.11: Visar OOP- och DOD-mätningen över minnesanvändningen. Mätvärdet visar medelvärdet av minnesanvändningen i GB. 42