• No results found

JAVASCRIPT OCH WEB WORKERS Parallellisering av en beräkningstung webbapplikation

N/A
N/A
Protected

Academic year: 2021

Share "JAVASCRIPT OCH WEB WORKERS Parallellisering av en beräkningstung webbapplikation"

Copied!
172
0
0

Loading.... (view fulltext now)

Full text

(1)

JAVASCRIPT OCH WEB WORKERS

Parallellisering av en beräkningstung

webbapplikation

JAVASCRIPT AND WEB WORKERS

Parallelization of a computationally heavy

web application

Examensarbete inom huvudområdet Datalogi Grundnivå 30 Högskolepoäng

Vårtermin 2013 Jesper Stråhle

Handledare: Henrik Gustavsson Examinator: Mikael Berndtsson

(2)

Sammanfattning

Webben används i allt större utsträckning som en riktig applikationsplattform, mycket tack vare HTML5. Detta ställer högre krav på webbapplikationens prestanda på klientsidan, då nya tekniker möjliggör mer avancerade applikationer. Parallellisering är en metod för att öka prestandan i applikationer, som dessutom tar nytta av de parallella arkitekturer som idag är vanliga. Web workers – ett nytt API för JavaScript – tillåter en enkel form av parallellisering för webbapplikationer. Dock har web workers en del begränsningar som minskar antalet möjliga strategier. Detta arbete syftar till att utvärdera hur valet av parallelliseringsstrategi påverkar prestandan hos en JavaScript-implementation av marching squares – en algoritm med goda möjligheter för parallellisering. Tre olika strategier implementeras, och utvärderas därefter genom prestandamätning. Resultaten visar att en strategi som använder så lite och så optimerad kommunikation som möjligt ger bättre prestanda än en strategi med mer kommunikation. Vidare arbete för att bland annat utvärdera vinsterna av delat minne föreslås.

Nyckelord: JavaScript, web workers, parallellisering, marching squares

(3)

Innehållsförteckning

1 Introduktion 1

2 Bakgrund 2

2.1 HTML5 . . . 2

2.2 Parallellisering . . . 3

2.3 Web workers . . . 4

2.4 Marching cubes/squares . . . 5

3 Problemformulering 8 4 Metod 9 4.1 Val av strategier . . . 9

4.2 Implementation . . . 9

4.3 Val av data . . . 9

4.4 Mätning . . . 10

5 Genomförande 11 5.1 Applikation . . . 11

5.2 Parallelliseringsstrategier . . . 12

5.2.1 Enskilda element per meddelande . . . 14

5.2.2 Enskilda rader av element per meddelande . . . 15

5.2.3 Flera rader av element per meddelande . . . 15

5.3 Optimeringar . . . 16

5.3.1 Minitest av ArrayBuffers som överförbara objekt . . . 18

5.4 Implementation av mätning . . . 18

6 Analys 21 6.1 Testplattform, parametrar och data . . . 21

6.2 Referensmätning . . . 21

6.3 Enskilda element per meddelande . . . 22

6.4 Enskilda rader av element per meddelande . . . 23

6.4.1 Kombinerad variant . . . 25

6.5 Flera rader av element per meddelande . . . 25

6.5.1 Kombinerad variant . . . 27

6.6 Sammanfattning . . . 27

7 Slutsatser 30 7.1 Resultatsammanfattning . . . 30

7.2 Diskussion . . . 30

7.2.1 Samhällsnytta . . . 31

7.3 Framtida arbete . . . 32

Referenser 34

(4)

1 Introduktion

Webbläsaren har gått från att vara en enkel plattform lämpad för simpla dokument, till att i allt större utsträckning användas som en riktig applikationsplattform (Anttonen m.fl., 2011;

Erbad m.fl., 2012). Detta innebär enligt Anttonen m.fl. (2011) att webbläsaren mer och mer tar över operativsystemets roll i att exekvera användarens applikationer. Anttonen m.fl. menar att HTML5, den nästkommande HTML-standarden, innehåller många nyheter som hjälper webben att bli en lämplig plattform för desktop-liknande applikationer. Denna utveckling har många fördelar: användare behöver inte längre installera och uppdatera applikationer själv, det är lätt att distribuera applikationer till användare över hela världen och dessa användare kan samarbeta och dela med sig av data på ett smidigt sätt. Denna utveckling skapar också ett större fokus på optimering av prestandan på klientsidan istället för att optimera nedladdning och tolkning av dokument (Erbad m.fl., 2012). Detta beror på att de möjligheter som idag finns tillgängliga för att skapa avancerade webbapplikationer ökar kraven på webbläsarens prestanda. Erbad m.fl. anser att det är just webbläsarens prestanda på klientsidan som oftast sätter gränser för vilka funktioner som kan implementeras. Optimeringar på klientsidan kräver ibland att viss funktionalitet elimineras eller förenklas, och denna situation blir svårare när utvecklare eftersträvar stöd för många webbläsare och plattformar (Erbad m.fl., 2012).

En metod för att öka prestandan i applikationer är parallellisering (Sait m.fl., 2005). Imple- mentation av en parallell applikation är enligt Gonçalves och Sobral (2012) en komplicerad uppgift, och den strategi som används kan enligt Bezbradica m.fl. (2012) ha en stor påverkan på resultatet. Tack vare web workers finns nu möjlighet till en enkel form av parallell exekvering för webbapplikationer skrivna i JavaScript (Erbad m.fl., 2012). Den enkla formen hos web workers begränsar antalet strategier som kan användas, vilket gör det desto svårare att implementera en effektiv parallellisering av ett komplext problem.

Detta arbete ska undersöka hur valet av parallelliseringsstrategi påverkar prestandan hos en beräkningsintensiv webbapplikation, skriven i JavaScript. Detta sker genom ett experiment där olika parallelliseringsstrategier för web workers jämförs med varandra genom prestanda- mätning. För denna jämförelse ska olika versioner av en webbapplikation implementeras och utvärderas. Den primära mätningen kommer ske på applikationens exekveringstid, där olika delmoment i applikationen även kommer mätas. Webbapplikationen ska hitta konturer i data given av användaren med hjälp av algoritmen marching squares.

Denna rapport är strukturerad på följande sätt. Kapitel 2 presenterar de bakomliggande områden som är relevanta för arbetet. Därefter beskrivs den problemformulering som gäller för arbetet i kapitel 3. Kapitel 4 presenterar den metod som kommer användas för att lösa problemet. Kapitel 5 beskriver genomförandet och implementationen av arbetet. Därefter analyseras resultatet av genomförda mätningar i kapitel 6. Till sist presenteras slutsatser samt framtida arbete i kapitel 7.

1

(5)

2 Bakgrund

I detta kapitel presenteras information och relaterad forskning kring relevanta områden för arbetet. Först beskrivs HTML5 och andra, relaterade webbstandarder i sektion 2.1. Därefter diskuteras parallellisering gällande dess fördelar och nackdelar i sektion 2.2. Sektion 2.3 presenterar web workers och dess funktionalitet. Slutligen beskrivs marching cubes/squares och deras användningsområden i sektion 2.4.

2.1 HTML5

HTML5 är den nästkommande standarden för HTML som utvecklas av World Wide Web Consortium (W3C) tillsammans med Web Hypertext Application Technology Working Group (W3C, 2012a; WHATWG, 2013a). Själva definitionen av HTML5 blev klar i slutet av 2012, och W3C jobbar nu för att publicera den färdiga standarden som en rekommendation under 2014 (W3C, 2012b).

Anttonen m.fl. (2011) anser att HTML5 innehåller många nyheter som ska hjälpa webben att bli en bättre applikationsplattform. Garaizar m.fl. (2012) har analyserat fördelar och nackdelar med att använda HTML5 för experiment och simulationer på webben, och de menar att de fördelar som finns mer än väl väger upp för nackdelarna (där de anger varierande stöd mellan plattformar som den största nackdelen).

Nyheter i HTML5 inkluderar bland annat fler semantiska element, som section och nav för att representera en generell sektion respektive navigation (W3C, 2012a). Andra nyheter är elementen audio och video, som används för att bädda in ljud och video direkt i webbsidor, utan att använda insticksmoduler såsom Flash eller liknande. En annan viktig del är canvas- elementet, som tillåter procedurellt genererad 2D-grafik som renderas direkt i webbläsaren (se figur 1). Garaizar m.fl. (2012) menar att dessa nya funkioner hos HTML5 är ett försök till att minska behovet av tredjepartstekniker – till exempel Flash, Java och Silverlight – som annars skapar en fragmenterad exekveringsmiljö på webben.

Vidare noterar Garaizar m.fl. (2012) att många tekniker som är relaterade till HTML5, men definierade i egna specifikationer, ofta benämns som HTML5 trots att de egentligen inte hör

Figur 1: Procedurellt genererad grafik med HTML5:s canvas-element.

2

(6)

dit. Ett exempel på en sådan teknik är WebGL, en webbvariant av OpenGL ES 2.0 som tillåter 3D-rendering direkt i webbläsaren med hjälp av det tidigare nämnda canvas-elementet. Ett annat exempel är WebSocket som möjliggör realtidskommunikation i full duplex mellan klient och server. Dessa nyheter (tillsammans med alla de som inte nämns här) öppnar upp stora möjligheter för framtidens webb.

2.2 Parallellisering

Asanovic m.fl. (2009) menar att IT-industrin kring processorer tog en abrupt vändning runt 2005. Vid denna tidpunkt började processorerna få flera kärnor, då det på grund av fysiska begränsningar inte längre gick att öka prestandan i enkärniga processorer genom att öka klockfrekvensen. Detta noterar även Gonçalves och Sobral (2012). Asanovic m.fl. (2009) menar att många företag tidigare hade försökt skapa en marknad för parallella datorer, men att de misslyckats på grund av att programmerare som är vana vid den ständigt ökande sekventiella prestandan inte hade något behov av att anamma parallellism.

Parallellisering ger goda möjligheter till förbättringar genom att exempelvis åstadkomma lägre exekveringstider för samma kvalitet på resultatet, eller komma fram till resultat av högre kvalitet på begränsad tid (Sait m.fl., 2005). Ett exempel på detta kan ses i figur 2. För att utnyttja dessa möjligheter måste applikationen anpassas till att exekveras parallellt (Gonçalves

& Sobral, 2012). Detta anses av Gonçalves och Sobral vara ett svårt jobb, som ofta kräver expertis inom parallella beräkningar.

Det finns många konkreta exempel på vinsterna av parallellisering. Perumalla och Aaby (2008) har, med hjälp av några olika typer av cellulära automater, utvärderat vinsterna av parallellisering genom att jämföra exekveringstider på en mångkärnig GPU (graphics processing unit) med exekveringstider på en dubbelkärnig CPU (central processing unit).

Resultatet visar tydligt högre hastigheter på GPU:n jämfört med CPU:n. Även Bezbradica m.fl.

(2012) har utvärderat vinsterna av att parallellisera cellulära automater. Deras experiment fokuserar på olika strategier för parallellisering på en superdator. Experimentet visar att en hybrid mellan parallellism på tråd- respektive processnivå ger bättre resultat än de två strategierna var för sig, vilket visar att strategin för parallellisering kan ha stor påverkan. Sait

A B C

A B

C

A B

C

D

E

F

Tid

G Kärna 2

Kärna 1 Kärna 1 Kärna 2 Kärna 1

Parallellt 2 Parallellt 1 Sekventiellt

Figur 2: Exempel på två olika typer av parallelliseringsvinster. Överst sker exekveringen sekventiellt. I mitten används parallellisering för att minska exekveringstiden för samma mängd arbete. Längst ner används parallellisering för att utföra mer arbete än den sekventiella varianten under samma tidsperiod.

3

(7)

m.fl. (2005) noterar att de strategier som finns tillgängliga för effektiv parallellisering till stor del styrs av den nivå av parallellism som problemet innehar. Detta påvisar svårigheten med parallellisering: valet av strategi har stor påverkan på resultatet, men samtidigt finns det ingen strategi som bevisligen är den mest effektiva eftersom olika strategier lämpar sig för olika typer av problem. Notera då att cellulära automater, som används av både Perumalla och Aaby (2008) samt Bezbradica m.fl. (2012), ofta har en mycket parallell natur (Bezbradica m.fl., 2012). Detta innebär att parallellisering av mer komplexa problem kan ge resultat som skiljer sig avsevärt från dessa två experiment.

2.3 Web workers

Erbad m.fl. (2012) menar att många webbapplikationer bygger på en händelsebaserad modell för att vara responsiva, men att dessa händelser ofta inte kan exekveras inom en rimlig tidsram när kraven överstiger tillgängliga CPU-resurser. De menar också att prestandan hos krävande webbapplikationer begränsas av den enkeltrådade exekveringen som vanligtvis används inom JavaScript. Parallell exekvering av JavaScript har tidigare inte varit möjlig, men tack vare web workers finns det nu möjlighet att skapa flertrådade webbapplikationer som kan ta nytta flerkärniga processorer (Erbad m.fl., 2012).

Web workers är ett API för JavaScript som möjliggör exekvering av skript i bakgrunden på en webbsida (WHATWG, 2013b). Web workers har vad Erbad m.fl. (2012) kallar en ”shared- nothing concurrency model”, vilket innebär att de inte delar någonting med varandra eller med huvudtråden. All form av kommunikation och synkronisering sker istället med hjälp av meddelandepassning.

Mozilla Developer Network (2013) noterar att web workers är mycket resistenta mot de problem gällande trådsäkerhet som annars är vanliga. Detta tack vare den mycket enkla kommunikationen som används, samt att web workers inte har tillgång till några som helst icke trådsäkra komponenter eller till DOM:en.

var myWorker = new Worker("background_script.js");

myWorker.postMessage("Hello, worker!");

myWorker.onmessage = function(event) {

console.log("Worker replied: " + event.data);

};

Figur 3: Exempelkod för att skapa och kommunicera med en web worker.

Web workers är mycket enkla att skapa och kommunicera med. Figur 3 visar hur ett nytt web worker-objekt skapas och hur kommunikationen sker. Till det worker-objekt som skapas går det att skicka meddelanden med hjälp av funktionen postMessage(). För att ta emot meddelanden behöver en händelsehanterare registreras hos objektet. Detta kan göras genom att tilldela en funktion till objektets onmessage-attribut. En worker kan ta emot och skicka meddelanden på samma sätt, men använder istället referensenself. Ett exempel på detta kan ses i figur 4.

De meddelanden som skickas till och från workers kopieras istället för att delas (Mozilla Developer Network, 2013). Detta innebär att huvudtråden och workern inte delar på samma instans av objekt som skickas, utan varje tråd har sin egen kopia. Meddelanden kan bestå av alla möjliga typer av data som går att serialisera, vilket gör det möjligt att skicka hela objekt.

4

(8)

self.onmessage = function(event) { if (event.data === "Hello, worker!") {

self.postMessage("Hello, master!");

} else {

self.postMessage("I don't understand ...");

} };

Figur 4: Exempelkod för en web worker som svarar på huvudtrådens meddelanden.

Erbad m.fl. (2012) har implementerat ett ramverk som utökar web workers funktionalitet genom att lägga till stöd för tillståndshantering och lastbalansering. Genom att använda ramverket för att parallellisera ett webbaserat spel har de visat att web workers kan leda till bättre timing och högre upplevd kvalitet hos spelet. Resultaten visar också att prestandan hos spelet kan skala linjärt med ett litet antal kärnor. Erbad m.fl. poängterar vikten av att välja rätt antal workers för en given implementation, då fler workers än nödvändigt, eller fler workers än antalet tillgängliga kärnor, kan sänka prestandan på grund av overhead. Då Erbads m.fl. (2012) resultat bygger på ett ramverk som utökar web workers, innebär det att resultatet inte nödvändigtvis påvisar effektiviteten hos web workers, utan snarare effektiviteten hos det implementerade ramverket.

Okamoto och Kohana (2010) använder i sitt experiment web workers för lastbalansering av ett webbaserat MORPG (Multiplayer Online Role-Playing Game). I grundversionen av spelet sköter servern all hantering av spelkaraktärer, vilket leder till hög belastning när många spelare är inloggade. Genom att istället använda en teknik där en del av belastningen fördelas på alla klienter med hjälp av web workers kan de sänka CPU-användningen på servern. Dock innebär denna förändring en högre kommunikationskostnad, vilket gör att Okamoto och Kohana anser att vidare utvärdering krävs för att förbättra tekniken.

2.4 Marching cubes/squares

Marching cubes är en algoritm utvecklad av Lorensen och Cline (1987). Denna algoritm skapar en 3D-modell utifrån skalärfält. Exempel på sådana skalärfält är data från datortomografi (CT) och magnetisk resonanstomografi (MRI). Data från sådana undersökningar presenteras vanligtvis som tvådimensionella bilder (Wu m.fl., 2010). Läkare kan sedan använda flera lager av bilder för att bilda sig en tredimensionell uppfattning av datan, vilket är komplicerat och kräver erfarenhet (Wu m.fl., 2010). Lorensen och Cline (1987) menar att de tredimensionella modeller som kan skapas med hjälp av marching cubes är mycket användbara verktyg som gör det lättare för personer att tolka datan, samt även kommunicera med andra kring dessa tolkningar.

Marching cubes tar emot data i form av tredimensionella fält och extraherar sedan en yta ur denna data (Wu m.fl., 2010). Genom att bilda kuber mellan en uppsättning av 8 punkter i datan, och sedan avgöra vilka av de 8 hörnpunkterna som tillhör respektive ligger utanför ytan baserat på ett isovärde (tröskelvärde), kan algoritmen approximera hur ytan skär genom kuben och applicera en yta utifrån en uppsättning förutbestämda ytor. Då kuben har 8 hörn finns det således 28 = 256 olika sätt som ytan kan skära genom kuben. Genom att gå igenom datan på detta sätt går det därmed att bygga upp en tredimensionell representation.

Marching squares är en tvådimensionell variant av marching cubes (Duke m.fl., 2008; Maple, 2003). Där marching cubes extraherar en yta extraherar marching squares istället en kontur

5

(9)

1 1 1 2 2 2 2 1 1 1 1 1 1 1 1

1 1 2 3 3 3 2 2 2 1 1 1 1

1 1 2 2 4 2 2 1 1 1

1

1 2 4 4 5 4 3 2 1 1

1 1 2 4 4 5 5 4 4 4 2 1 1

1

1 2 4 4 4 2 1 1

1 1 1 2 3 2 2 2 2 1 1

1

1 1 1 2 3 3 2 1 1 1 1 1 1

1

1 1 1 1 2 2 1 1 1 1 1 1 1

4 4 4 4

4

3

4 4

4 4

4 3

3

3

3 3

Figur 5: Kontur genererad med marching squares vid isovärdet 3,5. De grå numrerade rutorna visar originaldatan. Det streckade rutnätet visar de celler som skapas utifrån originaldatan. Den solida röda linjen visar den resulterande konturen. Observera att ingen interpolering sker.

(se figur 5). Detta sker på samma sätt som marching cubes, men kuberna byts ut mot fyrkanter som kallas celler (Duke m.fl., 2008). Då varje cell nu endast har 4 hörn reduceras antalet sätt som konturen kan skära genom cellen till 24= 16.

Huang m.fl. (2011) har använt marching squares för att automatiskt hitta kroppens kontur i CT-bilder. Detta är ett delsteg i en algoritm som automatiskt ska hitta ryggmärgskanalen i CT- bilder baserat på känd information såsom skala, position och andra anatomiska egenskaper hos kroppen och ryggmärgskanalen. Deras algoritm visar bättre resultat jämfört med att enbart mäta intensiteten i bilderna, och de anser att en utveckling av algoritmen kan göra det möjligt att hitta andra organ utifrån CT- och MRI-bilder. Wu m.fl. (2010) använder marching squares och marching cubes för att realisera ett interaktivt visualiseringssystem för medicinsk data.

I systemet används marching squares för att generera konturer som kan användas för att interaktivt välja isovärde för visualiseringen, då det annars är svårt för användaren att välja ett lämpligt värde. Wu m.fl. anser att det implementerade systemet är stabilt och användbart, och underlättar för visualisering av medicinsk data vid diagnosticering och behandlingsplanering.

Vidare utvärdering baserat på användartester krävs dock för att bekräfta resultatet, som i sin nuvarande form är helt partisk.

Dessa algoritmer kan även användas för annat än medicinsk data. Genom att modifiera marching squares och marching cubes har Maple (2003) skapat en metod för att approximera yta och volym. Maple menar att detta kan användas vid planering av utrymme när det finns geometriska begränsningar, såsom vid proteinmodellering, planering och design av golvutrymme samt planering av robotars rörelser. Müller m.fl. (2007) visar på en metod för att generera och rendera partikelbaserade vätskesimuleringar med hjälp av marching squares.

Med hjälp av denna metod kan de på ett effektivt sätt konstruera och visualisera ytor i realtid trots att beräkningen sker på CPU:n, och de noterar att en GPU-implementation borde ge betydligt högre prestanda. Müllers m.fl. (2007) utvärdering baseras dock endast på antal

6

(10)

bilder renderade per sekund, och det finns ingen beskrivning kring vilken nivå som anses vara

”effektiv”.

Newman och Yi (2006) noterar att även om marching cubes inte är den äldsta metoden för att generera ytor från data, så är den väldigt känd och välanvänd. De menar att detta delvis beror på dess raka, praktiska tillvägagångsätt. Vidare nämner Newman och Yi att marching cubes har applicerats inom mångra olika områden, bland annat biokemi, biomedicin, miljövetenskap, mekanik och dynamik. Denna bredd på användningsområden visar på styrkan och mångsidigheten hos algoritmen.

7

(11)

3 Problemformulering

Gonçalves och Sobral (2012) nämner att den prestandaökning som har skett i datorer de senaste åren har åstadkommits genom att öka antalet processorkärnor, istället för att öka klockfre- kvensen. De menar att denna förändring innebär ett större ansvar för mjukvaruutvecklaren när det gäller att öka prestandan i sina applikationer, då det inte längre går att förlita sig på snabbare processorer för att öka prestandan. Gonçalves och Sobral nämner att en effektiv parallellisering av ett program ofta är svår att uppnå, speciellt när parallelliseringen bygger på distribuerat minne. Erbad m.fl (2012) har, genom att implementera ett ramverk, visat att användning av parallellisering kan öka prestandan hos en avancerad webbapplikation som baseras på JavaScript. Deras ramverk bygger på web workers – ett relativt nytt API som tillåter parallellisering av JavaScript genom att köra skript i bakgrunden (WHATWG, 2013b).

Parallellisering med web workers är inte utan nackdelar (Erbad m.fl., 2012; Garaizar m.fl., 2012). Erbad m.fl. noterar att web workers inte har stöd för delat minne, vilket innebär att all kommunikation måste ske via meddelandepassning. Garaizar m.fl. (2012) nämner att web workers inte har tillgång till DOM:en, vilket innebär att all interaktion med webbsidan måste ske via huvudtråden. Garaizar m.fl. nämner också att web workers är relativt kostsamma att skapa, samt att de inte bör användas i stora antal. Dessa egenskaper hos web workers innebär att valet av strategi för parallellisering kan påverka slutresultatet avsevärt.

En algoritm vars prestanda kan tänkas förbättras av parallellisering är marching squares. Detta eftersom Duke m.fl. (2008) noterar att varje cell i beräkningen kan behandlas individuellt från övriga celler. Denna åsikt har även Newman och Yi (2006), som menar att marching cubes (den tredimensionella varianten av marching squares) har en ”inneboende parallellism”, vilket gör att det finns möjligheter till ökad prestanda genom parallellisering. Newman och Yi presenterar i sin undersökning flera olika exempel på parallellisering och lastbalansering av marching cubes, vilket tydligt visar att parallelliseringen kan ske på många olika sätt. Problemet är att det inte alltid är självklart vilken strategi som är den mest effektiva. Marching squares kan vara mer intressant för parallellisering än simplare algoritmer, som fraktaler och cellulära automater, då den kräver fler steg som gör den svårare att parallellisera. Dessa egenskaper hos web workers och marching squares gör det intressant att undersöka om de kan kombineras på ett effektivt sätt. Detta arbete ska därför undersöka följande fråga:

Hur påverkas prestandan hos en JavaScript-implementation av marching squares beroende på valet av parallelliseringsstrategi?

En kombination av marching squares och web workers är inte bara intressant ur en programme- ringsmässig synpunkt. Tillämpningar av denna typ har länge varit vanliga som rena desktop- applikationer, men en webbaserad tillämpning skulle öppna upp för de många fördelar och möjligheter som webben ger (Anttonen m.fl., 2012). Bland dessa fördelar märks bland annat enkel distribution, plattformsoberoende samt den spridning som webben tillåter.

8

(12)

4 Metod

Både Hansen och Hinker (1992) samt Bezbradica m.fl. (2012) utför experiment för att utvärdera vinsterna av parallellisering på ett effektivt sätt. Ett experiment kommer därför användas för att utvärdera problemformuleringen i detta arbete. Problemet är av kvantitativ natur vilket innebär att mätning är lämpligt i experimentet (Berndtsson m.fl., 2008). Kvalitativa metoder som intervjuer, enkäter och liknande skulle kunna användas för att få respons från riktiga användare angående hur de upplever applikationen och dess prestanda, vilket är en viktig punkt. Dock ligger fokus i detta arbete endast på den kvantifierbara prestandan hos implementationen, vilket leder till att endast mätning kommer användas. I detta experiment kommer några olika strategier för parallellisering användas för att implemetera marching squares i en webbapplikation. Dessa implementationer kommer sedan prestandamätas för att se vilken påverkan valet av strategi har genom att jämföra de olika implementationerna med varandra (Bezbradica m.fl., 2012). En sekventiell variant kommer också implementeras för att användas som referens i mätningen. Prestandamätningen har till syfte att utvärdera hur väl de olika strategierna lämpar sig till att parallellisera beräkningar av denna typ med hjälp av web workers.

4.1 Val av strategier

Då web workers endast har tillgång till meddelandepassning går det inte att jämföra med andra övergripade parallelliseringsstrategier som exempelvis trådning med delat minne. För detta arbete kommer de olika strategierna istället representera olika sätt att använda web workers och hur data delas upp mellan trådar. Några parametrar som kan varieras mellan dessa strategier är exempelvis hur ofta meddelanden skickas samt storleken på dem. Den specifika identifieringen av de strategier som ska användas sker under genomförandet.

4.2 Implementation

Applikationen som kommer implementeras är en klientbaserad webbapplikation. Den ska ta emot data från användaren och applicera marching squares för att hitta konturer i den givna datan, baserat på de parametrar som specificerats. Implementationen av applikationen kommer delas upp i ett antal steg. Varje steg går då att testa och utvärdera individuellt. De olika implementationsstegen är tätt kopplade till de olika steg som marching squares består av:

1. Traversera igenom data given av användaren och generera celler utifrån specificerade parametrar.

2. Tilldela en passande linje för varje cell.

3. Applicera linjär interpolering för att skapa mer korrekta linjer.

4. Rita ut linjerna med hjälp av canvas-elementet i HTML5.

En variant av parallelliseringen kommer även kombinera steg 1–3 till ett steg. Detta förväntas minska antalet meddelanden som skickas mellan huvudtråden och alla workers, vilket ger möjlighet till en potentiell prestandaökning.

4.3 Val av data

Som testdata för applikationen kommer röntgenbilder från National Human Genome Research Institute (2012) användas. Dessa bilder är allmän egendom och får därför användas fritt. Det kommer inte presenteras någon information kring var, när eller på vem röntgenundersökning- arna har genomförts på, vilket eliminerar risken för kränkning av personlig integritet.

9

(13)

4.4 Mätning

Hansen och Hinker (1992) har i sitt experiment utvärderat vinsterna av parallellisering hos marching cubes genom prestandamätning av implementationen. Även Bezbradica m.fl. (2012) samt Perumalla och Aaby (2008) använder liknande metoder för att utvärdera parallellise- ringsvinsterna hos cellulära automater. En liknande prestandamätning kommer användas för att utvärdera implementationerna i detta arbete. Exekveringstiden kommer mätas för hela proceduren, det vill säga tiden det tar att beräkna samt rita upp de resulterande linjerna utifrån den givna datan. Exekveringstiden kommer även mätas för de olika delmomenten i proceduren och algoritmen, vilket gör det lättare att se hur varje enskild del påverkas av parallellisering. En liknande mätning av alla delmoment används av Hansen och Hinker (1992). Denna mätning kommer ske med några olika dataset av olika storlekar. Prestandamätningen kommer byggas in i själva applikationen, vilket gör den helt självständig och resultatet blir därför inte beroende av det mätverktyg som används. Både Hansen och Hinker (1992) samt Bezbradica m.fl. (2012) genomför sina mätningar med olika antal processorer/kärnor för att se hur det påverkar prestandan. På ett liknande sätt utför Erbad m.fl. (2012) sina mätningar med olika antal web workers, vilket även kommer ske för mätningarna i detta arbete.

Mätningarna kommer genomföras på olika webbläsare för att jämföra eventuella skillnader.

Ahmadi m.fl. (2012) har visat att JavaScript-prestandan kan skilja sig avsevärt mellan olika webbläsare, vilket gör det intressant att se om det även gäller för denna typ av problem. De webbläsare som kommer användas är Google Chrome och Mozilla Firefox, då dessa verkar vara de två vanligaste webbläsarna som har stöd för web workers i sina nuvarande versioner (Mozilla Developer Network, 2013). Från och med version 10 har även Internet Explorer stöd för web workers, men denna version finns bara tillgänglig för Windows och kommer därför inte användas i prestandamätningarna. Även Safari har stöd för web workers, men i och med version 6 finns webbläsaren bara tillgänglig för OS X och kommer därför inte inkluderas i mätningarna.

Prestandamätningarna kommer även ske på olika operativsystem, för att se om prestandan kan skilja sig även på denna punkt. De operativsystem som kommer användas för testerna är Windows 7 och OS X Mountain Lion. Tack vare att mätningarna genomförs på olika webbläsare och olika operativsystem säkerställs att mätresultaten inte enbart representerar en specifik webbläsare eller ett specifikt operativsystem.

För att säkerställa återupprepbarhet och verifierbarhet av experimentet kommer samtliga versionsnummer för webbläsare samt operativsystem prestenteras i samband med redovisning av mätresultaten. Där kommer det även specificeras vilken hårdvara mätningarna genomförs på, samt information kring den specifika testdata som används. Samtliga resultat från mätning- arna, samt den kod som produceras, kommer presenteras i bilagor.

10

(14)

5 Genomförande

I detta kapitel beskrivs arbetet med att implementera webbapplikationen. I sektion 5.1 ges en övergripande beskrivning av hur applikationen är uppbyggd och hur den fungerar. Därefter beskriver sektion 5.2 vilka parallelliseringsstrategier som valts för arbetet, samt hur de olika strategierna har implementerats i applikationen. I sektion 5.3 förklaras hur tidiga versioner av applikationen har optimerats för att ge högre prestanda, samt vilka områden som fortfarande är i behov av en förbättring. Till sist beskriver sektion 5.4 hur prestandamätningen har implementerats i applikationen, samt vilka mätvärden som sparas. Samtliga delar av den producerade koden finns tillgänglig i appendix A.

5.1 Applikation

Webbapplikationen som implementerats är en helt klientbaserad, händelsedriven applikation.

Gränssnittet erbjuder kontroller där användaren kan ställa in följande parametrar: strategi för generering av celler, linjer, samt interpolering av linjer; kombinerad strategi för de tre föregående stegen; storleksförhållande mellan faktiska pixlar och cellpixlar; isovärde; antal workers; samt vilka delar av resultatet som ska ritas ut. Figur 6 visar applikationens gränssnitt.

Genom att dra och släppa en bildfil inom det markerade området kan användaren importera en bild till applikationen. Den importerade bilden kommer då ritas ut i ett canvas-element. Där- efter läses bilddatan från canvasen och konverteras till svartvitt, för att sedan skrivas tillbaka

Figur 6: Webbapplikationens användargränssnitt.

11

(15)

Start

Kombinera steg?

Rita linjer

Generera interpolerade linjer från pixlar Generera celler

från pixlar

Interpolera linjer

Nej Ja

Generera linjer från celler

Figur 7: Övergripande flödesschema över algoritmens exekvering.

till canvasen. Konverteringen till svartvitt görs för att säkerställa att samtliga färgkanaler i varje pixel har samma värde, och detta värde kan sedan mappas mot ett cellhörn.

När algoritmen startar sker en nedsampling av originalbilden. Detta sker genom att rita bilden nedskalad till en annan canvas, där skalan bestäms av användaren via gränssnittet. Från den nedskalade bilden i canvasen kan bildata sedan läsas och användas som utgångspunkt för att generera celler. De genererade cellerna används sedan för att generera linjer, som i sin tur interpoleras för att skapa en mer korrekt kontur. Flödesschemat i figur 7 ger en överblick över denna process. Notera att den högra vägen i schemat är en kombinerad variant av de tre stegen till vänster, och utför dessa tre steg internt (mer om detta i sektion 5.3).

Resultatet av algoritmen ritas sedan ut i ett lager ovanför originalbilden. Vad som ska ritas ut specificeras av användaren via inställningarna i gränssnittet. I figur 6 ritas endast de interpolerade linjerna ut.

5.2 Parallelliseringsstrategier

Samtliga parallelliseringsstrategier som används är varianter av en strategi som Bezbradica m.fl. (2012) kallar ”scatter–gather”. Denna strategi bygger på att huvudtråden delar upp datan som ska beräknas i lika stora delar. Dessa delar skickas sedan ut (scatter) till slavprocesser som beräknar de enskilda delarna. Huvudtråden samlar sedan in den returnerade datan (gather), och sammanfogar resultatet.

Varje kombination av parallelliseringsstrategi och algoritm-steg är implementerad som en egen klass i applikationen. Tack vare detta är det enkelt att byta den strategi som används för varje steg i algoritmen. Genom att lagra klassnamnet i en variabel går det vid exekveringen att avgöra vilken typ av parallellisering som ska användas. Ett kodexempel på detta kan ses i figur 8. Hos

12

(16)

// Start generating cells

var cellGenerator = new window[settings.cellGenerator]();

cellGenerator.onComplete = generateLines;

cellGenerator.start();

Figur 8: Exempelkod för att vid exekvering avgöra vilken strategi som ska användas vid generering av celler.

varje objekt registreras en så kallad callback, vilket är den funktion som objektet ska anropa när den är klar. Detta asynkrona upplägg är nödvändigt eftersom de strategier som använder web workers kommunicerar asynkront och därför kommer returnera innan alla workers har skickat tillbaka sina resultat. I kodexemplet i figur 8 registreras funktionengenerateLinessom den callback som ska anropas när alla celler har genererats.

Varje strategi för parallellisering har implementerats enligt samma upplägg. Detta upplägg bygger på att först initiera alla workers, och skicka ut grundläggande data till dem. När funktionenstart() anropas på objektet skickas samtliga jobb ut till alla workers genom att loopa igenom datan som ska skickas ut, eller genom att loopa igenom alla workers. När en worker skickar tillbaka ett svar till objektet skickas det till funktionen onWorkerMessage(). Denna funktion tar emot den beräknade datan, och kopierar den till den eller de globala datastrukturer som används för att samla resultatet. När samtliga utskickade jobb är klara, anropas den registrerade callback-funktionen, som sparats i objektetsonComplete-attribut. Ett flödesschema för detta upplägg kan ses i figur 9. Notera att varje worker kan ta emot flera jobb, och behandlar dem i den ordning de tas emot, eftersom de läggs i händelsekön för respektive worker.

Start

Initiera worker

Alla workers initierade?

Skicka ut jobb

Alla jobb skickade?

Alla jobb mottagna?

Ta emot jobb

Anropa callback Ja

Ja

Ja

Nej Nej

Nej

Figur 9: Övergripande flödesschema över parallelliseringen.

13

(17)

Worker 1 Worker 2 Worker 3 Worker 4

Figur 10: Exempel på parallell datadekomposition där varje element i listan skickas i ett enskilt meddelande.

5.2.1 Enskilda element per meddelande

Denna strategi bygger på att datan delas upp i enskilda element (celler eller linjer), där varje element sedan kan skickas ut till en worker för beräkning. Då web workers inte är lämpliga att använda i stora antal (Garaizar m.fl., 2012) är det inte passande att skapa en worker för varje element. Istället skickas elementen ett i taget ut till nästa tillgängliga worker i listan, och när den når slutet av listan på workers börjar den om från början igen. Denna strategi resulterar i en jämn distribuering av datan, där många meddelanden skickas, och varje meddelande innehåller en liten mängd data. Ett exempel på detta kan ses i figur 10.

Denna strategi används av följande klasser:ParallelCellGenerator1,ParallelLineGenerator1,

ParallelLineInterpolator1ochParallelMarchingSquares1. Figur 11 visar ett kodexempel där pixeldatan delas upp i enskilda celler, och varje cell skickas i ett enskilt meddelande till en worker.

var workerIndex = 0;

for (var rowIndex = 0; rowIndex < cells.height; rowIndex++) {

for (var columnIndex = 0; columnIndex < cells.width; columnIndex++) { ... // Creating message buffer and filling it with pixels and header data

// Transfer the message buffer to the worker

this.workers[workerIndex].postMessage(messageBuffer, [messageBuffer]);

this.numJobsSent++;

// Set up worker index for the next cell

workerIndex = ++workerIndex % this.workers.length;

} }

Figur 11: Uppdelning av pixeldata i enskilda element.

14

(18)

Worker 1 Worker 2 Worker 3 Worker 4

Figur 12: Exempel på parallell datadekomposition där varje rad av element i listan skickas i ett enskilt meddelande.

5.2.2 Enskilda rader av element per meddelande

I denna strategi delas datan upp i större grupper av element. Varje rad av element bildar en grupp, som sedan kan skickas ut till en worker för beräkning. Det totala antalet meddelanden som skickas ut är därför lika med antalet rader av element. Denna strategi resulterar därmed i färre meddelanden jämfört med föregående strategi, men varje meddelande innehåller i sin tur mer data. Ett exempel på denna strategi kan ses i figur 12.

Denna strategi används av följande klasser:ParallelCellGenerator2,ParallelLineGenerator2

ochParallelMarchingSquares2. Figur 13 visar ett kodexempel där datan delas upp i rader av celler, och varje rad skickas i ett enskilt meddelande till en worker. Notera att denna strategi inte används vid interpolering av linjer därför att linjerna inte är sorterade, vilket gör det svårare att effektivt hitta alla linjer som tillhör en viss rad av celler. Det är inte heller säkert att linjerna är jämnt distribuerade över alla rader av celler – vissa rader kan innehålla många linjer, medan andra rader kan vara helt tomma.

for (var rowIndex = 0; rowIndex < cells.height; rowIndex++) {

... // Creating message buffer and filling it with pixels and header data

// Transfer the message buffer to the worker

this.workers[rowIndex % this.workers.length].postMessage(messageBuffer, [ messageBuffer]);

this.numJobsSent++;

}

Figur 13: Uppdelning av pixeldata i rader.

5.2.3 Flera rader av element per meddelande

Denna strategi delar upp datan i större grupper än föregående strategi, genom att flera rader grupperas tillsammans. Varje grupp av rader kan sedan skickas ut till en worker för beräkning i ett meddelande. Det totala antalet meddelanden som skickas ut är i den här strategin lika med antalet workers. Den här strategin resulterar därför i ett lägre antal meddelanden än båda de föregående strategierna, men varje meddelande innehåller då också en större mängd data. Ett exempel på denna strategi kan ses i figur 14.

15

(19)

Worker 1 Worker 2 Worker 3 Worker 4

Figur 14: Exempel på parallell datadekomposition där flera rader av element skickas i ett enskilt meddelande.

Denna strategi används av följande klasser:ParallelCellGenerator3,ParallelLineGenerator3,

ParallelLineInterpolator2ochParallelMarchingSquares3. Figur 15 visar ett kodexempel där datan delas upp i grupper av rader, och varje grupp skickas i ett enskilt meddelande till en worker. Vid interpolering av linjer delas inte linjerna in i rader, utan alla linjer grupperas istället i så lika stora grupper som möjligt.

var numRowsLeft = cells.height;

var rowIndex = 0;

for (var i = 0; i < this.workers.length; i++) { // Determine the number of rows for this worker

var numRows = Math.ceil(numRowsLeft / (this.workers.length - i));

numRowsLeft -= numRows;

... // Creating message buffer and filling it with pixels and header data

// Transfer the message buffer to the worker

this.workers[i].postMessage(messageBuffer, [messageBuffer]);

this.numJobsSent++;

// Set up row index for the next worker rowIndex += numRows;

}

Figur 15: Uppdelning av pixeldata i grupper av rader.

5.3 Optimeringar

Under arbetets gång har implementationen gradvis förändrats för att öka prestandan. Ett exempel på en sådan förändring är skiftet från vanliga JavaScript-arrayer till ArrayBuffers där det är lämpligt. ArrayBuffers är statiska arrayer som representerar binära data buffers (Mozilla Developer Network, 2012). Fördelen med dessa i jämförelse med vanliga arrayer, är att ArrayBuffers är så kallade ”överförbara objekt”, vilket innebär att datan i en ArrayBuffer kan överföras till en worker, istället för att kopieras via strukturerad kloning (Mozilla Developer

16

(20)

// Determine offsets for pixels to copy

var startOffset = cellImageData.width * rowIndex * 4;

var endOffset = cellImageData.width * (rowIndex + numRows + 1) * 4;

var message = {

type: 'generateRows',

data: cellImageData.data.subarray(startOffset, endOffset), rowIndex: rowIndex,

numRows: numRows };

Figur 16: Tidig implementation med dynamiska arrayer.

Network, 2013). Detta kan innebära stora prestandaförbättringar vid överföring av större mängder data. En annan fördel med ArrayBuffers är att storleken kan optimeras, till exempel används 8-bitars heltal för att representera all hörndata och alla cellindex i applikationen, då de inte kräver storleken som finns tillgänglig hos vanliga heltal i JavaScript. Nackdelen med ArrayBuffers är att innehållet i den ArrayBuffer som överförs inte längre finns tillgängligt från sändarens sida, vilket gör att sändaren endast kan överföra ArrayBuffers som den har råd att bli av med.

I denna implementation måste datan delas mellan flera workers, och det passar därför inte att föra över all data till en worker i form av ett överförbart objekt. Istället används ArrayBuffers genom att kopiera en delmängd av exempelvis pixeldatan till en mindre ArrayBuffer, som sedan kan föras över till en worker. Även om det fortfarande sker en kopiering, så är denna kopiering mer effektiv än att skicka datan till en worker via strukturerad kloning (se sektion 5.3.1). Då ArrayBuffers är statiska lämpar de sig inte lika väl för data som är dynamisk i storlek, som exempelvis listan över linjer i applikationen. På grund av detta lagras alla linjer i en vanlig dynamisk JavaScript-array, medan hörnvärden och cellindex sparas i statiska ArrayBuffers.

Figur 16 visar en tidigare implementation av cellgenerering med vanliga JavaScript-arrayer, medan figur 17 visar den slutliga implementationen med ArrayBuffers.

var messageBuffer = new ArrayBuffer(8 + (cellImageData.width * (numRows + 1) * 4));

// Create header and data views on the message buffer var message = {

header: new Uint32Array(messageBuffer, 0, 2), data: new Uint8Array(messageBuffer, 8)

};

// Set header data

message.header[0] = rowIndex;

message.header[1] = numRows;

// Determine offsets for pixels to copy

var startOffset = cellImageData.width * rowIndex * 4;

var endOffset = cellImageData.width * (rowIndex + numRows + 1) * 4;

// Copy pixels from the cell image data

message.data.set(cellImageData.data.subarray(startOffset, endOffset));

Figur 17: Slutlig implementation med statiska ArrayBuffers.

17

(21)

Tabell 1: Jämförelse med avseende på RTT mellan att skicka en ArrayBuffer till en worker som ett överförbart objekt i förhållande till strukturerad kloning. Alla tider anges i millisekunder.

Webbläsare Strukturerad kloning Överförbart objekt Skillnad

Chrome 26 153,6 40,2 −73,8 %

Firefox 20 246,6 95,6 −61,2 %

Vidare har även en kombination av de tre första stegen i algoritmen implementerats som ett parallelliseringssteg för varje strategi. I dessa implementioner skickas pixeldata ut till workers, som sedan skickar tillbaka interpolerade linjer (se figur 7). Detta upplägg minskar antalet meddelanden som skickas fram och tillbaka mellan workers och huvudtråden, och ökar andelen arbete som utförs i varje worker. Detta har gjorts för att se om prestandan påverkas till det bättre när antalet meddelanden som skickas fram och tillbaka minskas till ett minimum.

Ett område som fortfarande är i behov av optimering är parallell interpolering av linjer. I detta steg krävs tillgång till de hörnvärden som ligger på varje sida om start- och slutpunkterna för varje linje. Då det inte finns någon explicit koppling mellan varje linje och dess hörnpunkter, så finns det inget effektivt sätt att hitta endast de hörnpunkter som behövs vid interpoleringen (utan att inspektera start- och slutpunkterna för varje linje). I denna implementation får varje worker därför en kopia av all hörndata vid initieringen, även om det endast är en delmängd som används.

5.3.1 Minitest av ArrayBuffers som överförbara objekt

För att utvärdera den potentiella prestandavinsten av att skicka ArrayBuffers som överförbara objekt istället för att använda strukturerad kloning har ett minitest genomförts. Tabell 1 visar resultatet av detta test där 64 MiB slumpmässig data skickas från huvudtråden till en worker och tillbaka igen. Notera att datan kopieras innan den förs över som ett överförbart objekt, detta för att likna hur ArrayBuffers var tänkta att användas i applikationen. De angivna tiderna är genomsnittet av 5 genomförda tester. Plattformen som testerna utfördes på har en 2,4 GHz Intel Core 2 Duo, 8 GB 1067 MHz RAM och körde OS X 10.8.3. Resultaten visar mellan 61,2 % och 73,8 % lägre round-trip time (RTT) när datan skickas som ett överförbart objekt. Samtlig kod för testet finns i appendix A.7.

5.4 Implementation av mätning

Prestandamätningen är inbyggd i applikationen genom att registrera en tidsstämpel i början av algoritmen, och sedan registrera en tidsstämpel efter varje steg. Kodexemplet i figur 18 visar hur de två första tidsstämplarna registreras. Detta upplägg fortsätter på samma sätt för de resterande momenten – direkt efter varje steg registreras en tidsstämpel och sedan påbörjas nästa steg. Följande tidsstämplar registreras: start av algoritm, slut på generering av celler, slut på generering av linjer, slut på interpolering av linjer samt slut på utritning av linjer (som också innebär slutet av algoritmen).

När hela algoritmen är klar och alla tidsstämplar har registrerats, kan de resulterande exekve- ringstiderna sparas i en samling arrayer hos ett objekt genom att beräkna skillnaden mellan tidsstämplarna (se exempelkod i figur 19). Utskriften av de beräknade exekveringstiderna kan sedan ske genom att anropa en funktion via webbläsarens JavaScript-konsol. Ett exempel på detta kan ses i figur 20. Genom att endast ta enkla tidsstämplar under algoritmens gång, för att sedan beräkna exekveringstiderna när algoritmen är klar, minimeras prestandamätningens påverkan på resultatet.

18

(22)

function generateCells() { ...

// Mark the start time

timestamps.started = Date.now();

... // Generating cells }

function generateLines() { // Finished generating cells

timestamps.generatedCells = Date.now();

... // Generating lines }

Figur 18: De första tidsstämplarna registreras i algoritmen.

function draw() {

// Finished interpolating lines

timestamps.interpolatedLines = Date.now();

... // Drawing lines

// And we're done!

timestamps.finished = Date.now();

// Save the resulting execution times saveResults();

...

}

function saveResults() {

var totalTime = timestamps.finished - timestamps.started;

var drawTime = timestamps.finished - timestamps.interpolatedLines;

if (settings.combinedStrategy === 'none') {

var cellTime = timestamps.generatedCells - timestamps.started;

...

results.cells.push(cellTime);

...

} else {

var marchTime = timestamps.interpolatedLines - timestamps.started;

combinedResults.march.push(marchTime);

...

} }

Figur 19: De sista tidsstämplarna registreras och exekveringstiderna beräknas och sparas.

19

(23)

Figur 20: Utskrift av mätresultat i webbläsarens JavaScript-konsol.

20

(24)

6 Analys

I detta kapitel presenteras och analyseras de mätresultat som samlats in vid prestandamät- ningar av applikationen. Analysen fokuserar främst på mätningar med det större datasetet (se sektion 6.1). Samtliga mätresultat finns tillgängliga i appendix B.

6.1 Testplattform, parametrar och data

Alla mätningar har utförts på en och samma dator med en 2,4 GHz Intel Core 2 Duo och 8 GB 1067 MHz RAM. De operativsystem som används är OS X 10.8.3 samt Windows 7 Professional med Service Pack 1. De webbläsare som används är de senaste versionerna av Chrome och Firefox för respektive operativsystem. Detta är vid mättillfället Chrome 26.0.1410.65 för både OS X och Windows, samt Firefox 20.0 och 20.0.1 för OS X respektive Windows.

Prestandamätningarna utfördes således på fyra olika plattformar, där ”plattform” innebär en kombination av en webbläsare och ett operativsystem.

För mätningarna används två dataset av olika storlekar – ett större och ett mindre. Det större datasetet består av en bild med dimensionerna 2400 × 3197 pixlar, medan det mindre datasetet består av en bild med dimensionerna 707 × 580 pixlar. Dessa bilder är röntgenbilder från National Human Genome Research Institute (2012). Samtliga figurer i detta kapitel bygger på data från mätningar med det större datasetet. Vid samtliga mätningar används en pixelskala på 2 och ett isovärde på 128 (för det större datasetet) eller 64 (för det mindre datasetet). Dessa parametrar resulterar i 1 918 800 cellhörn, 1 916 002 celler samt 34 994 linjer för det större datasetet. För det mindre datasetet är motsvarande siffror 102 660 cellhörn, 102 017 celler samt 1596 linjer. Det större datasetet är då cirka 1769 % större än det mindre datasetet när det gäller pixlar, cellhörn och celler, och cirka 2093 % större när det gäller linjer.

Alla parallella strategier prestandamäts med 1, 2, 4 och 8 workers för att se hur prestandan på- verkas i förhållande till antalet workers. Varje kombination av strategi, dataset, antal workers, webbläsare och operativsystem prestandamäts 10 gånger, och från dessa resultat beräknas ett medelvärde. Det är dessa medelvärden av exekveringstider som används i detta kapitel, om inget annat anges. Det större datasetet tillsammans med den första parallelliseringsstrategin (enskilda element per meddelande) visade sig dock vara så långsam att endast 3 mätningar med varje kombination genomfördes. Då den andra strategin, enskilda element per meddelande, inte finns tillgänglig för interpolering av linjer (se sektion 5.2.2), används vid mätningarna istället strategin flera rader av element per meddelande för detta delmoment.

6.2 Referensmätning

Den sekventiella varianten av applikationen har genomgått samma prestandamätningar som de parallella implementationerna, dock utan variation av workers då det inte är tillämpligt.

Resultaten från dessa mätningar används senare som referens vid jämförelse med resultat från de parallella strategierna.

Figur 21 visar resultaten från prestandamätningar av den sekventiella implementationen vid användning av det större datasetet. Figuren visar tydligt på den största skillnaden mellan plattformarna, vilken är att Firefox på OS X är extremt mycket långsammare i utritningssteget, med exekveringstider för detta steg som ligger 1439 % till 3115 % högre än övriga plattformar.

Ett annat område med stora skillnader är generering av celler, där Chrome på både OS X och Windows är långsammare än Firefox på de båda operativsystemen. Här ligger exekverings- tiderna för Chrome 298 % till 395 % högre. Även vid generering och interpolering av linjer

21

(25)

Chrome (OS X) Chrome (Win) Firefox (OS X) Firefox (Win) 0

100 200 300 400 500 600

700 Celler

Linjer Interpolering Utritning Totalt

Tid (ms)

Figur 21: Exekveringstider för den sekventiella implementationen.

ligger Chrome på de båda operativsystemen något efter Firefox. Vid generering av linjer är exekveringstiderna 37 % till 81 % högre, och vid interpolering av linjer ligger exekveringstiderna 46 % till 190 % högre. Chrome är däremot snabbare när det kommer till utritning jämfört med Firefox på Windows, med exekveringstider som är 48 % till 52 % lägre.

Sammantaget ligger de totala exekveringstiderna för Chrome på både OS X och Windows cirka 155 % högre än Firefox på Windows, som är den snabbaste plattformen för den sekventiella implementationen med det större datasetet. Firefox på OS X har i sin tur 397 % högre exekveringstid än Firefox på Windows, och här är då utritningen den stora flaskhalsen.

6.3 Enskilda element per meddelande

Som tidigare nämts i sektion 5.2.1 resulterar denna strategi i ett stort antal meddelanden, där varje meddelande innehåller en liten mängd data. Mätningarna visar att detta ger väldigt höga exekveringstider i förhållande till den sekventiella implementationen. Figur 22 visar hur prestandan hos implementationen av denna strategi påverkas av antalet workers som används vid exekvering med det större datasetet. Där ser vi att exekveringstiden i det bästa fallet (Chrome på Windows med 1 worker) är cirka 450 gånger högre än det sämsta fallet med sekventiell exekvering (Firefox på OS X). Vid användning av det mindre datasetet är exekveringstiden cirka 300 gånger högre.

När det gäller den kombinerade varianten av denna strategi så är skillnaden mindre, men det är fortfarande betydligt högre exekveringstider även här. Vid användning av det större datasetet har det bästa parallella fallet (Chrome på Windows med 1 worker) en exekveringstid som är cirka 250 gånger högre än det sämsta sekventiella fallet. Byter vi ut datasetet mot det mindre är exekveringstiden cirka 160 gånger högre.

Orsaken till de höga exekveringstiderna för denna strategi kan tänkas vara den höga kom- munikationskostaden mellan workers och huvudtråden, något som Erbad m.fl. (2012) anser är en stor begränsning hos web workers. Erbad m.fl. menar att kommunikationskanalerna måste optimeras i webbläsarna för att tillåta högre skalbarhet. På grund av dessa extremt höga exekveringstider i förhållande till den sekventiella varianten, kommer ingen vidare analys av exekveringstiderna för de olika delmomenten i applikationen diskuteras, utan denna strategi kan snabbt avfärdas som en effektiv strategi för parallellisering med web workers.

22

(26)

1 2 4 8 0

100 000 200 000 300 000 400 000 500 000 600 000

Chrome (OS X) Chrome (Win) Firefox (OS X) Firefox (Win)

Antal workers

Tid (ms)

Figur 22: Exekveringstider för enskilda element per meddelande.

6.4 Enskilda rader av element per meddelande

Denna strategi, som resulterar i lägre antal meddelanden än föregående strategi (se sektion 5.2.2), visar sig vara mer effektiv. Figur 23 visar hur den totala exekveringstiden för appli- kationen påverkas av det antal workers som används tillsammans med det större datasetet.

Figuren visar en tydlig prestandaförbättring när vi går från 1 till 2 workers (bortsett från Firefox på OS X, som endast visar en svag prestandaförbättring). Därefter sker ingen vidare förbättring, utan exekveringstiden blir något högre ju fler workers som används. Värt att nämna är att vid användning av det mindre datasetet stiger exekveringstiderna kraftigare vid användning av 4 och 8 workers. Här är exekveringstiderna för 8 workers 47 % till 72 % högre än exekveringstiderna för 2 workers, medan motsvarande skillnad för det större datasetet är 4 % till 7 %. Det optimala antalet workers verkar därför vara 2, lika många som antalet kärnor i processorn på testplattformen. Detta stämmer överens med Erbads m.fl. (2012) åsikt om att antalet workers bör vara lika med antalet tillgängliga kärnor för bästa resultat.

1 2 4 8

0 500 1000 1500 2000 2500 3000 3500

Chrome (OS X) Chrome (Win) Firefox (OS X) Firefox (Win)

Antal workers

Tid (ms)

Figur 23: Exekveringstider för enskilda rader av element per meddelande.

23

(27)

Chrome (OS X) Chrome (Win) Firefox (OS X) Firefox (Win) 0

500 1000 1500 2000

2500 Celler

Linjer Interpolering Utritning Totalt

Tid (ms)

Figur 24: Exekveringstider för enskilda rader av element per meddelande (2 workers).

Figur 24 visar exekveringstider för de olika delmomenten i denna strategi vid användning av 2 workers tillsammans med det större datasetet. Vad som är mest intressant här är att Chrome är snabbare än Firefox när det handlar om generering av celler, det vill säga förhållandet är omvänt i jämförelse med den sekventiella varianten. Exekveringstiderna för Chrome är på detta steg 1,3 % till 41 % lägre än motsvarande exekveringstider för Firefox. Trots detta omvända förhållande är exekveringstiderna för generering av celler högre än motsvarande tider för den sekventiella varianten på samtliga plattformar. För Chrome är exekveringstiderna 84 % och 36 % högre på OS X respektive Windows. För Firefox är skillnaden ännu större, med exekveringstider som är 1040 % och 645 % högre på OS X respektive Windows. Dessa prestandaskillnader mellan parallell och sekventiell exekvering är ännu högre för det mindre datasetet, med Firefox på Windows som den enda avvikande plattformen där skillnaden är relativt likvärdig med skillnaden för det större datasetet.

Nästkommande steg, generering av linjer, är långsammare än föregående steg på samtliga plattformar, vilket även det är ett omvänt förhållande i jämförelse med den sekventiella varian- ten. Likt generering av celler är detta steg långsammare i denna parallella variant på samtliga plattformar i jämförelse med den sekventiella varianten. För Chrome är exekveringstiderna 1643 % och 1371 % högre på OS X respektive Windows. För Firefox är tiderna 2924 % och 2259 % högre på OS X respektive Windows. Precis som föregående steg är prestandaskillnaderna mellan den parallella och den sekventiella varianten större vid användning av det mindre datasetet för Chrome, medan dessa skillnader är mindre för Firefox.

Även det sista parallella steget, interpolering av linjer, är långsammare än motsvarande steg i den sekventiella varianten. För Chrome är exekveringstiderna 2187 % och 2037 % högre på OS X respektive Windows. För Firefox är dessa tider 1073 % och 1915 % högre på OS X respektive Windows. I likhet med tidigare steg är prestandaskillnaden mellan parallell och sekventiell exekvering med det mindre datasetet större för alla plattformar jämfört med det större datasetet. Det enda undataget är Firefox på Windows, där prestandaskillnaden är mycket lägre.

Då utritningen inte går att parallellisera, och därför är likadan för alla strategier, bör det inte vara några större prestandaskillnader för detta steg, vilket mätningarna bekräftar. När det gäller den totala exekveringstiden är samtliga plattformar långsammare än den sekventiella

24

(28)

Chrome (OS X) Chrome (Win) Firefox (OS X) Firefox (Win) 0

500 1000 1500 2000 2500

Normal

Kombinerad

Tid (ms)

Figur 25: Jämförelse i exekveringstid mellan normal och kombinerad variant av enskilda rader av element per meddelande (2 workers).

varianten. För det större datasetet är de totala exekveringstiderna mellan 294 % och 1009 % högre än den sekventiella varianten, medan tiderna för det mindre datasetet är mellan 465 % och 1087 % högre.

6.4.1 Kombinerad variant

Den kombinerade varianten av denna strategi är märkbart snabbare än dess normala mot- svarighet, vilket kan ses i figur 25. Exekveringstiderna är mellan 27 % och 65 % lägre vid användning av det större datasetet, och mellan 32 % och 52 % lägre vid användning av det mindre datasetet. Trots detta är exekveringstiderna fortfarande högre än den sekventiella varianten på samtliga plattformar. Den totala exekveringstiden är mellan 154 % och 550 % högre vid användning av det större datasetet. Vid användning av det mindre datasetet är exekveringstiderna mellan 237 % och 472 % högre.

6.5 Flera rader av element per meddelande

Den här strategin, som resulterar i lägst antal meddelanden, visar sig också vara den mest effektiva av alla strategier. Figur 26 visar hur den totala exekveringstiden påverkas när antalet workers varieras tillsammans med det större datasetet. I figuren syns, likt den föregående strategin, en tydlig prestandaförbättring när vi går från 1 worker till 2. Precis som föregående strategi blir det inte heller någon vidare prestandaökning när antalet workers ökas till 4 och 8, utan varierar mellan ungefär samma nivå till något sämre. Likheterna med föregående strategi fortsätter även när det kommer till mätresultaten för det mindre datasetet, där också denna strategi visar kraftigare stigning av exekveringstider när antalet workers ökar. Här är exekveringstiderna för 8 workers mellan 81 % och 133 % högre än för 2 workers, och motsvarande siffror för det stora datasetet ligger mellan 0,13 % lägre och 7,06 % högre. Dessa resultat indikerar, precis som föregående strategi, att det optimala antalet workers är lika med antalet tillgängliga processorkärnor.

I figur 27 presenteras exekveringstiderna för de olika delmomenten i algoritmen, vid använd- ning av 2 workers tillsammans med det större datasetet. Likheterna med föregående strategi fortsätter då exekveringstiderna för generering av celler i Chrome är lägre än motsvarande tider för Firefox. Samtliga plattformar har dock en prestandaökning jämfört med föregående strategi,

25

(29)

1 2 4 8 0

500 1000 1500 2000 2500 3000 3500

Chrome (OS X) Chrome (Win) Firefox (OS X) Firefox (Win)

Antal workers

Tid (ms)

Figur 26: Exekveringstider för flera rader av element per meddelande.

och här är exekveringstiderna för Chrome på OS X och Windows 13,1 % respektive 31 % lägre än exekveringstiderna för den sekventiella varianten. Exekveringstiderna för Firefox är dock 413 % och 287 % högre på OS X respektive Windows i förhållande till den sekventiella varianten.

Prestandaskillnaderna mellan parallell och sekventiell exekvering för det mindre datasetet är högre på samtliga plattformar för denna strategi, och ingen plattform är här snabbare än den sekventiella varianten.

Generering av linjer är betydligt långsammare än föregående steg för Chrome, medan skillna- den mellan stegen på Firefox är minimal. Gemensamt för samtliga plattformar är dock att de presterar sämre än den sekventiella varianten för detta steg. För Chrome på OS X och Windows är dessa exekveringstider 1292 % respektive 1269 % högre än motsvarande tider vid sekventiell exekvering, medan tiderna för Firefox är 573 % och 736 % högre på OS X respektive Windows.

För alla plattformar ökar prestandaskillnaden mellan den sekventiella varianten och denna parallella strategi när det mindre datasetet används, med Firefox på Windows som det enda undataget på grund av en lägre prestandaskillnad.

Chrome (OS X) Chrome (Win) Firefox (OS X) Firefox (Win) 0

500 1000 1500 2000

2500 Celler

Linjer Interpolering Utritning Totalt

Tid (ms)

Figur 27: Exekveringstider för flera rader av element per meddelande (2 workers).

26

References

Related documents

Men i detta yttrande har vi inte kunnat göra en helhetsbedömning av de olika målens bidrag till samhällsekonomin utan fokuserar på kriterier för effektiva styrmedel och åtgärder

Byanätsforum vill först och främst förtydliga att vi inte tar ställning till huruvida bredbandsstödet bör finnas med i framtida GJP eller om det uteslutande ska hanteras inom

Det finns ett stort behov av att den planerade regelförenklingen blir verklighet för att kunna bibehålla intresse för att söka stöd inom landsbygdsprogrammet 2021–2027, samt

Ekoproduktionen bidrar till biologisk mångfald även i skogs- och mellanbygd genom att mindre gårdar och fält hålls brukade tack vare den för många bättre lönsamheten i

Om forskning inte kommer att hanteras inom CAP samtidigt som budgeten för det nationella forskningsprogrammet för livsmedel är osäker så kommer innovations- och

Uppnås inte detta får vi aldrig den anslutning som krävs för vi skall kunna klara de målen som vi tillsammans behöver nå framöver i fråga om miljö, biologisk mångfald och

För att få arbetskraft till lantbruket måste arbetsgivare säkerställa att de anställda har en god arbetsmiljö samt bra arbetsvillkor och löner. Om vi inte arbetar aktivt med

Detta gäller dels åtgärder som syftar till att minska jordbrukets inverkan på klimatet, dels åtgärder för att underlätta för jordbruket att anpassa sig till ett ändrat