• No results found

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

N/A
N/A
Protected

Academic year: 2021

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

Copied!
65
0
0

Loading.... (view fulltext now)

Full text

(1)

En jämförelse mellan

dataorienterad design och

objektorienterad design

(2)

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,

(3)

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

(4)

Förord

(5)

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

(6)

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

(7)

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.

(8)

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]

(9)

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.

(10)

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].

(11)

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].

(12)

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

(13)

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.

(14)

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.

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.

M1 Undersöka och beskriva för- och nackdelar med respektive designteknik genom genomsökning av litteratur/artiklar M2 Implementera respektive designteknik under utvecklingen

av en simulering med hjälp av Unity i programmeringsspråket C#

M3 Utföra experimentet på de bägge designteknikerna

(15)

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.

(16)

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].

(17)

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].

(18)

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

(19)

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

(20)

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].

(21)

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.

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.

Resurser Miljö 1 Miljö 2 Miljö 3

Processor Intel Core

(22)

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.

(23)

3.4

Etiska överväganden

(24)

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.

(25)
(26)

Figur 4.2: Visar simuleringens explosion då alla kuber sätts i rörelse.

(27)
(28)

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].

(29)

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].

(30)

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.

(31)

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.

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

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

(32)

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.

Tabell 5.2: Visar de framkomna nackdelarna med OOP.

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].

OOP nackdel

Antal artiklar / Totalt antal

artiklar Artikel källa

Prestandakrävande 11 / 17

[3], [29-31], [34-37], [39], [41],

[43], Koden har en tendens att bli rörig och

kräver därför ordentlig planering samt

kunskap 6 / 17

[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

(33)

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.

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.

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]

DOD nackdel

Antal artiklar / Totalt antal

artiklar Artikel källa

(34)

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

Nivåer Antal kuber

Nivå 1 3000

Nivå 2 5000

(35)

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.

(36)

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.

(37)

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.

(38)

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.

(39)

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.

(40)

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.

(41)

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.

(42)

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.

(43)

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.

(44)

Figur 5.14: Visar ett linjediagram över medelvärden från tabell 5.11.

Från början var meningen att även grafikkortsanvändningen skulle mätas. Detta valdes att utelämnas då GPU-profilern kräver mycket resurser och därför är avstängd som standardläge i profileringsverktyget [50].

(45)

6

Analys

Detta kapitel presenterar en analys av de resultat som finns redovisade i föregående kapitel.

6.1

Systematisk litteraturundersökning

En systematisk litteraturundersökning utfördes för att ta reda på för- och nackdelar med respektive designteknik. Denna metod ska leda fram till svaren på frågorna “vilka kända för- och nackdelar finns det med de respektive teknikerna?” samt “ökar DOD komplexiteten på koden?”.

I OOP-undersökningen där 17 artiklar användes uppgavs den allra vanligaste fördelen vara att OOP möjliggör återanvändning av kod. Denna fördel nämns i 9 av de 17 artiklarna. Just arv som är ett sätt att återanvända kod medför dock även att prestandan försämras. Vilket dessutom var den vanligaste nackdelen som nämndes med OOP, prestandakrävande (11/17). På andra plats, bland OOP:s fördelar, kom lätt att underhålla koden (8/17). Lätt är ju dock ett värdeord så det den ena tycker är lätt kan den andra tycka är svårt och vise versa. Det som uppfattas som lätt eller svårt bottnar ju även delvis i tidigare kunskaper och erfarenheter. Som motpol till denna fördel uppkom även som den andra vanligaste nackdelen att koden har en tendens att bli rörig och kräver därför ordentlig planering samt kunskap (6/17). Återigen så uppkommer ett godtyckligt ord, rörig, i detta sammanhang. Relaterat till denna nackdel var att OOP-program är mycket större än andra program (4/17).

På delad tredjeplats av OOP:s fördelar kom att objekten som används reflekterar den mänskliga verkligheten (6/17) samt säkerhet som representeras bl a i form av inkapsling. Dessa är dock ännu något som bidrar till att OOP blir mer prestandakrävande då objekten som byggs upp använder sig av arv. Inkapslingen medför att man använder getters och setters för att komma åt privata variabler.

2/17 artiklar tog upp att OOP sänker programmingskostanden. Medan 4/17 artiklar uppgav att OOP-möjliggjorde parallell utveckling samt var bra för GUI-programmering (2/17). Att den parallella utvecklingen förenklades hade att göra med just organiseringen i objekt vilket gör det lättare att dela upp koden mellan olika utvecklare. Att koden blir lättare att dela upp kan vara en bidragande faktor till att programmeringskostanden sänks. Att OOP skulle lämpa sig väl för GUI-programmering togs upp i artiklar som diskuterade både OOP och DOD. Då nämndes som anledning att just GUI-programmeringen inte är lika beroende av prestanda. Det uppkom även att OOP-koden var komplex att parallellisera (3/17) samt att det inte är en lämplig lösning för alla typer av problem (2/17). Att det inte är en lämplig lösning för alla typer av problem är dock något som mest troligtvis stämmer in på alla typer av tekniker, så även på DOD.

(46)

användes endast 4 olika artiklar. Detta var dock något som var relativt förväntat då DOD är betydligt mer okänt och obeprövat än vad OOP är.

DOD:s främsta fördel uppgavs vara att det blev cachevänligare kod som leder till färre cachemissar (3/4). På andra plats nämnda i 2/4 artiklar kom de resterande fördelarna lättare att parallellisera i jämförelse med OOP, lätt att förstå och underhålla koden samt lätt att testa. Just cachevänligare kod och lättare att parallellisera är bägge bidragande faktorer till en mer prestanda vänlig kod. Den enda nackdelen som togs upp var att det tar tid att lära sig och kräver en del övning. Detta nämns i 2 av 4 artiklar.

6.2

Kontrollerade experiment

Ett kontrollerat experiment utfördes för att mäta FPS, processoranvändning samt minnesanvändning av respektive designteknik. Denna metod ska leda fram till svaret på frågorna “är DOD ett bättre designval än OOP vid prestandakrävande applikationer?”, “hur stor blir prestanda skillnaden mellan de olika designteknikerna?” samt “finns det möjlighet att utveckla mindre prestandakrävande program endast genom att ändra designteknik?”.

6.2.1 Miljö 1

(47)

När man kör applikationerna syns det att simuleringen med nivåökningen laggar allt mer. DOD-versionen visar dock alltid mindre prestandapåverkan än vad OOP-versionen gör. På nivå 3 märks detta extra tydligt då simuleringen är skriven att köra 600 frames. Det blir då en enorm skillnad i hur länge simuleringen körs. OOP-simuleringen körs i 5 minuter och 48 sekunder medan DOD-versionen endast tar 39 sekunder. Detta var något som blev väldigt tydligt då jag höll på med mätningarna då OOP-mätningarna i miljö 1 på nivå 3 tog betydligt längre tid att utföra. Detta beror på att OOP-versionen tappar många fler frames än vad DOD-versionen gör.

Granskar man linjediagrammet, figur 5.4 som presenterar medelvärdet på hur många ms processorn måste jobba per frame, syns det att OOP-grafens lutning är betydligt brantare än DOD-grafens. Man ser att nivå 2 och nivå 3 i OOP-versionen är så pass höga att de hamnar utanför diagrammet medan DOD-versionen har en mycket mindre ökning. I tabell 5.6, som visar de exakta mätningarna, går det att se denna markanta skillnad mellan de olika nivåerna i exakta siffror.

I figur 5.5, som visar ett linjediagram över medelvärdet av minnesanvändning, syns det att OOP-versionen har en höjning av användning av minnet på varje nivå medan DOD-versionen är mer stabil. DOD-versionens minnesanvändning är i stort sätt samma oberoende av nivå. Den gröna linjen som visar DOD mätningen är horisontell utan lutning och ligger stabilt. De exakta värdena visas i tabell 5.7 där det syns att OOP-simuleringen ökar mer markant i takt med stigande nivå än vad DOD-simuleringen gör.

6.2.2 Miljö 2

(48)

för att sedan relativt snabbt gå ner och lägga sig mellan 30 FPS och 60 FPS med ett par spikes strax under 30 FPS. DOD-versionens graf ser man överdelen av under hela körningen. I början ligger den på strax under 30 FPS för att sedan lägga sig runt 60 FPS resterande del av körningen. DOD-simuleringens graf ligger lägre och har färre och lägre peakar än OOP-simuleringens graf. I figur 5.8, som visar nivå 3, syns ej den övre delen av grafen i OOP-versionen. Den ligger under hela körningen under 30 FPS. Man kan även se att den ligger under linjen för 15 FPS då nedre delen av denna etikett skymtas svagt i bilden. DOD-versionen ligger i början av körningen så pass högt att övre delen av grafen inte syns i bild. Den går sedan ner och lägger sig mellan 30 FPS till 60 FPS. I figur 5.9, som visar ett linjediagram över medelvärdet på hur många ms processorn måste jobba per frame, syns det att​när simuleringen ligger på nivå 1 så är inte skillnaden så stor mellan de olika versionerna. Men när de kommer upp på nivå 2 så blir skillnaden mellan OOP och DOD:s processortid större. Vid nivå 3 är skillnaden markant mycket större än vid nivåerna innan. Precis som i miljö 1 går det även i denna miljö att se att OOP-mätningarna över processoranvändningen ökar markant snabbare i jämförelse med DOD-simuleringen.

Denna miljö var den miljö som nivåerna togs fram i. Därmed blev denna miljö den miljön som den visuella laggningen visar störst skillnad mellan de olika versionerna i. DOD-versionen började visa lagg först på nivå 3 och detta enbart i början av körningen. Medan OOP-versionen visade lite lagg i nivå 1 för att sedan bli allt tydligare.

Tabell 5.9 visar att minnesanvändningen ständigt ökar för varje körning i båda simuleringarna. Dessa mätvärden betraktas därför inte som trovärdiga.

6.2.3 Miljö 3

Denna miljö visade inte någon större skillnad på de olika versionerna. OOP-versionen började lagga lite smått i början av körningen av nivå 2. Detta lagg blev tydligare i nivå 3. DOD-versionen visade dock inte något lagg på någon av nivåerna i denna miljö.

(49)

ligger OOP-mätningen något högre än DOD-mätningen. I början maxar OOP-mätningen under 15 FPS en kort stund för att sedan gå ner och lägga sig runt 30 FPS och fortsättningsvis lägga sig relativt stabilt över 60 FPS med en del spikes. DOD-versionen ligger i början också under 15 FPS. Men detta är under kortare tid än OOP-versionen. DOD-versionen lägger sig sedan mellan 30 FPS och 60 FPS för att sedan fortsättningsvis lägga sig över 60 FPS med undantag från vissa spikes som i sämsta fall hamnar på 30 FPS korta stunder. Här ligger DOD-versionen mer stabilt med färre antal spikes. De spikes som dock finns är högre och går därmed lägre i FPS än OOP. Men detta sker endast under kortare stunder. Det är först på nivå 3, figur 5.12, som man ​ser en något större skillnad mellan de olika simuleringsversionerna i jämförelse med nivå 2. OOP-körningen ligger nu högre i ms än DOD-körningen i början. OOP ligger på under 30 FPS vid start, för att sedan gå ner och lägga sig runt 60 FPS med vissa spikes som vid ett fåtal tillfället går ner mot 30 FPS. DOD-körningen ligger runt 30 FPS för att sedan gå ner och lägga sig relativt stabilt med mindre spikes än OOP på strax över 60 FPS resterande del av körningen. Sammanfattningsvis kan man genom att titta på de olika nivåerna och jämföra deras grafer, se att de olika versionerna i denna miljö använder nästan lika mycket av processorn. Det är först i nivå 3 som man kan ana en viss skillnad till DOD:s fördel. Tittar man i figur 5.13 ser man att OOP-mätningen och DOD-mätningen nästan är identisk. Det är först på nivå 3 som det ser ut som att graferna börjar skilja sig. Här är det även noterbart att i nivå 1 så ligger OOP för första gången under DOD i processoranvändning. Denna skillnad är dock väldigt marginell vilket går att se i tabell 5.10 som presenterar de exakta värdena.

Figur 5.14 visar precis som figur 5.5, i miljö 1, att OOP-simuleringen ökar mer i minnesanvändningen mellan de olika nivåerna än vad DOD-simuleringen gör. Detta visas av att OOP-grafen har en brantare lutning än vad DOD-grafen har.

6.2.4 Slutsats

(50)

motsvarande graf för miljö 3, figur 5.13, ser man att graferna skär varandra ända till nivå 3 där man kan ana en viss skillnad. Miljö 3 erbjuder starkare hårdvaruresurser än miljö 2 i förhållande till hur prestandakrävande applikationen är. Skulle man fortsätta att öka antalet rörliga enheter till mer än 7000 skulle troligtvis liknande skillnad mellan de två versionerna även synas i miljö 3.

(51)

7

Diskussion

I detta kapitel diskuteras arbetets resultat samt om frågorna från frågeställningen har besvarats.

7.1

Systematisk litteraturundersökning

Syftet med den systematiska litteraturundersökningen är att utifrån andras erfarenheter ta reda på kända för och nackdelar med respektive teknik. Det är även att mer specifikt undersöka om komplexiteten på koden ökar om man använder sig utav DOD.

Vilka kända för- och nackdelar finns med de respektive teknikerna?

Det flest artiklar tar upp som fördel med OOP att det möjliggör återanvändning av kod (9/17). Klasser som ärver varandra är ett sätt att återanvända kod i OOP. Något som bör tas med i beaktning här är att detta även påverkar prestandan. Därför är det viktigt att tänka på att inte låta dessa klasshierarkier bli alltför djupa. Använder man sig av ett ramverk så har man även den koden att ta hänsyn till. T ex så är Unitys Monobehaviour klass med i ett arvhierarki som är 3 klasser djup. Dock använder sig inte min egenskrivna kod av något arv.

Den näst vanligaste fördelen med OOP är att koden är lätt att underhålla (8/17). Detta är ju dock en subjektiv åsikt och beror lite på vad man jämför med och vad man har i bagaget. I OOP organiseras koden upp i olika objekt. Vilket leder in på det som är den tredje fördelen nämligen att objekten som används reflekterar den mänskliga verkligheten. Då programmering lätt kan uppfattas som något abstrakt så blir ju just OOP pedagogiskt på det sättet att objekten reflekterar verkligheten. Det blir på något sätt mer logiskt, vilken kod som ska ligga var och vilka objekt som ska ingå i systemet samt hur de ska samverka och skicka meddelande mellan varandra. Här kan man dra paralleller längre historiskt tillbaka till programmering då vi innan programmeringsspråken fanns fick skriva binär maskinkod. Detta vidareutvecklades till programmeringsspråk för att det skulle bli lättare för människan att programmera. Vilket i sin tur förenklades ännu mer för människans skull då OOP uppkom och resulterade i kod som delas in i objekt som kommunicerar med varandra.

OOP:s inkapsling nämns också som en fördel bland annat med argumentet att det förstärker säkerheten (6/17). Det framkom även att OOP möjliggör parallell utveckling (4/17), sänker programmeringskostnaden (2/17) samt fungerar bra för GUI-programmering (2/17).

References

Related documents

▸ För att få ’loose coupling’ vill vi inte vara beroende av en specifik klass, det är bättre om vi kan bero av ett interface, så att vi senare kan välja vem som skall göra

Dränvatten från bergtunnlar och bergschakt innehåller höga kvä- vehalter och kommer inte att kunna användas för infiltration.. Under byggtiden fordras tillfälliga sänkningar av

Interaktionsdesign – “den process som ordnas inom begränsade resursramar för att skapa, forma och fastställa de bruksorienterade egenskaper (strukturella, funktionella,

Flaggor: N: Ettställs om resultatets teckenbit (bit 7) får värdet 1. Z: Ettställs om samtliga åtta bitar i resultatet blir noll. Beskrivning: Data växlas mellan angivna

Övergången från filtrerings- och slussan- vändning till beredskapsläge görs enligt följande:.. - Öppna slusstältets dragkedjor helt och öppna kardborrbanden i dragkedjornas

För att verkligen spegla situationen skulle ett objekt KUNDINKÖP vara med också (med relationer till de relevanta händelseklasserna) med syfte att identifiera varje inköpsärende

While the majority of today's high-rise structures use a strong central core made out of high strength concrete as the main load carrying structure (CTBUH, 2010), the Tubed Mega

Cílem práce bylo navrhnout rám elektromobilu eTUL, také zkontrolovat jeho pevnost a tuhost. Torzní tuhost rámu elektromobilu se po optimalizaci zvýšila o 96 %,