• No results found

Studie av utvecklingsverktyg med inriktning mot PLC-system (HS-IDA-EA-99-103) Christoffer Brax (a96chrbr@ida.his.se) Institutionen för datavetenskap Högskolan i Skövde, Box 408 S-54128 Skövde, SWEDEN

N/A
N/A
Protected

Academic year: 2021

Share "Studie av utvecklingsverktyg med inriktning mot PLC-system (HS-IDA-EA-99-103) Christoffer Brax (a96chrbr@ida.his.se) Institutionen för datavetenskap Högskolan i Skövde, Box 408 S-54128 Skövde, SWEDEN"

Copied!
71
0
0

Loading.... (view fulltext now)

Full text

(1)

Studie av utvecklingsverktyg med inriktning mot PLC-system

(HS-IDA-EA-99-103)

Christoffer Brax (a96chrbr@ida.his.se) Institutionen för datavetenskap

Högskolan i Skövde, Box 408 S-54128 Skövde, SWEDEN

Examensarbete på program för systemprogrammering under vårterminen 1999.

(2)

Studie av utvecklingsverktyg med inriktning mot PLC-system

Examensrapport inlämnad av Christoffer Brax till Högskolan i Skövde, för Kandidatexamen (B.Sc.) vid Institutionen för Datavetenskap.

99-06-18

Härmed intygas att allt material i denna rapport, vilket inte är mitt eget, har blivit tydligt identifierat och att inget material är inkluderat som tidigare använts för erhållande av annan examen.

Signerat: _______________________________________________

(3)

Studie av utvecklingsverktyg med inriktning mot PLC-system Christoffer Brax (a96chrbr@ida.his.se)

Sammanfattning

Datoranvändningen i samhället växer för varje dag. Det är då viktigt att programvara håller hög kvalité, då vissa programvaror styr kritiska maskiner som exempelvis flygplan. Ett sätt att få kvalitativa programvaror är att använda bra utvecklingsverktyg. I detta arbete utvärderas fem olika utvecklingsverktyg: GNAT (Ada), Microsoft Visual C++, Microsoft J++, Borland Delphi och Active Perl.

Inriktningen på utvärderingen är mot utveckling av programvara för PLC-system. Det som utvärderats är effektivitet av genererad kod, kompileringstid, storlek på genererad kod, kodportabilitet och utbud av färdiga komponenter. Undersökningen har genomförts med hjälp av praktiska tester.

Nyckelord: Kompilering, PLC-system, Benchmark, Utvecklingsverktyg, Realtidssystem

(4)

Innehållsförteckning

1 Introduktion ...1

2 Bakgrund och begrepp...2

2.1 Utvecklingsprocessen vid programvaruutveckling ... 2

2.2 Allmänt om utvecklingsmiljöer... 2

2.3 Allmänt om kompilatorer ... 2

2.4 Programmeringsspråk som ingår i de utvärderade utvecklingsverktygen... 5

2.4.1 C/C++ ... 5

2.4.2 Pascal ... 6

2.4.3 Java ... 6

2.4.4 Ada/Ada95 ... 7

2.4.5 Perl... 7

2.5 Realtidssystem... 7

2.6 PLC-system ... 8

3 Problemprecisering ...9

3.1 Problemformulering ... 9

3.1.1 Kvantitativa kriterier... 9

3.1.2 Kvalitativa kriterier... 9

3.1.3 Undersökningskriterier ... 10

3.1.4 Val av programmeringsspråk för undersökningen ... 10

3.2 Avgränsning ... 11

4 Metoder...13

4.1 Jämförelse av metoder... 13

4.1.1 Kvantitativa kriterier... 13

4.1.2 Kvalitativa kriterier... 15

4.2 Vald metod ... 15

4.3 Precisering av utvärderingskriterier för undersökningen ... 15

4.4 Benchmarks ... 17

4.4.1 Språkfunktionstester ... 17

4.4.2 Testfall för kodeffektivitet ... 18

4.4.3 Testfall för kompileringshastighet ... 19

5 Genomförande ...20

(5)

5.1 Förutsättningar för tester ... 20

5.2 Effektivitet hos genererad kod ... 21

5.2.1 Loop overhead ... 21

5.2.2 Lokal variabeltilldelning... 22

5.2.3 Global variabeltilldelning ... 22

5.2.4 Matristilldelning ... 23

5.2.5 Uppräkning av 8-bitarsvariabel ... 23

5.2.6 Uppräkning av 16-bitarsvariabel ... 24

5.2.7 Uppräkning av 32-bitarsvariabel ... 24

5.2.8 Uppräkning av 64-bitarsvariabel ... 25

5.2.9 Uppräkning av 64-bitars flyttalsvariabel ... 25

5.2.10 Matrisallokering ... 26

5.2.11 Funktionsanrop... 27

5.2.12 Anrop av matematisk funktion 1 ... 27

5.2.13 Anrop av matematisk funktion 2 ... 28

5.2.14 Villkorstest ... 29

5.2.15 Strängallokering ... 29

5.2.16 Typecasting ... 30

5.2.17 Rekursivt anrop ... 31

5.2.18 Lintest... 31

5.3 Kompileringshastighet... 32

5.4 Storlek på kompilerad kod ... 33

5.4.1 Filstorlekar vid kodeffektivitetstester ... 33

5.4.2 Filstorlekar vid kompileringshastighetstester ... 34

5.5 Kodportabilitet... 35

5.6 Utbud av färdiga komponenter... 36

6 Analys av resultat ...37

6.1 Slutsatser av kvantitativa undersökningar... 37

6.1.1 Kodeffektivitet... 37

6.1.2 Kompileringshastighet ... 38

6.1.3 Storlek på kompilerad och länkad kod ... 38

6.2 Slutsatser av kvalitativa undersökningen ... 39

6.2.1 Kodportabilitet... 39

6.2.2 Utbud av färdiga komponenter ... 40

(6)

7 Sammanfattning ...41

7.1 Framtida arbete... 42

Referenser...43

Bilaga A. Källkod för benchmarkprogram...1

Källkod för Ada-program ... 1

Källkod för C++-program... 2

Källkod för Javaprogram ... 6

Källkod för Delphiprogram ... 12

Källkod för Perlprogram ... 16

Bilaga B. Poäng vid betygsbedömningar...1

(7)

1 Introduktion

1 Introduktion

I takt med att samhället blir mer och mer datoriserat så ökar kraven på tillförlitlighet hos produkter som innehåller mikroprocessorer.

Dessa produkter är numera inte bara PC-datorer utan även mobiltelefoner, mikrovågsugnar, bilar, industriella styrsystem, TV-apparater etc. Detta leder till att större krav ställs på programvarorna. En bil får till exempel inte börja accelerera okontrollerat för att programvaran är felaktig. Kravet på tillförlitliga programvaror för dessa system ökar. Det finns många aspekter som måste beaktas när ett system med krav på tillförlitlighet ska utvecklas. Dels så måste själva hårdvaran vara av bra kvalité, om hårdvaran går sönder leder detta ofta till att systemet ”går ner”.

Idag är det vanligare att det är något fel på mjukvaran än på hårdvaran i ett system.

Detta beror på att mjukvaran ofta blir väldigt komplex och är svårare att kontrollera än hårdvaran. Ett sätt att få en programvara som är tillförlitlig är att använda ett utvecklingsverktyg som underlättar för programmeraren. Med tillförlitlighet (eng.

reliability) menas att en programvara uppför sig på det sätt den är avsedd att göra i alla situationer (även i onormala situationer).

Vid val av utvecklingsverktyg finns det många aspekter att ta hänsyn till. Dels själva utvecklingsmiljön, vilka hjälpmedel det finns som förenklar arbetet och dels själva kompileringsdelen som innehåller kompilatorn, bibliotekshanterare, länkare och avlusare. Det är också viktigt att utvecklingsverktyget är anpassad till den typ av applikation som ska skrivas. Varje program har speciella krav på funktionalitet, och vissa program kan till exempel ha krav på att utföra sina uppgifter inom en förutbestämd tid. Dessa kallas realtidssystem, på denna typ av system ställs speciella krav på kompilatorn för att systemet ska uppfylla vissa kriterier, som exempelvis förutsägbarhet och punktlighet. I andra system är dessa krav inte alls lika viktiga och där kanske andra aspekter hos kompilatorn är mer betydande som exempelvis kompileringshastighet, avlusningsmöjligheter och inbyggda funktioner.

Utveckling av programvara är ofta en itererande process. Detta innebär bland annat att själva kompileringen måste utföras många gånger under utvecklingsarbetet. Det är då en fördel om kompileringstiden är kort, vilket leder till kortare väntetider för utvecklaren. Andra detaljer som är viktiga är hur väl de olika delarna i utvecklingsmiljön är integrerade med varandra, hur felsökning kan göras och hur bra stöd för tredjepartsbibliotek som finns.

I detta arbete utvärderas ett antal utvecklingsmiljöer. Dessa är baserade på ett antal olika programmeringsspråk. De språk som används är C/C++, Pascal, Java, Ada och Perl. Inriktningen på utvärderingen kommer att vara mot PLC-system (Programable Logic Controller). PLC-system är mycket vanliga inom industrin där de används för att styra allt ifrån dörrar och fönster till stora maskiner.

Vid utvärderingen används ett antal utvärderingskriterier. Dessa kriterier är prestanda vid kompilering, prestanda vid exekvering av kompilerad kod, storlek på genererad kod, kodportabilitet och utbud av färdiga komponenter.

(8)

2 Bakgrund och begrepp

2 Bakgrund och begrepp

Detta avsnitt beskriver centrala begrepp som används i detta arbete. Här beskrivs även de fem olika programmeringsspråken som ingår i de utvärderade utvecklingsverktygen.

2.1 Utvecklingsprocessen vid programvaruutveckling

Enligt Pressman (1997) finns det ett antal olika modeller som beskriver utvecklingsprocessen vid programvaruutveckling. En vanlig modell är den som Pressman kallar för spiralmodellen. Spiralmodellen är en iterativ modell som består av ett antal olika faser, vanligtvis mellan tre och sex. Under utvecklingen växlar arbetet mellan dessa olika faser ett antal varv tills det att den utvecklade programvaran är klar.

De faser som Pressman tar upp är: kundkontakt, planering, riskanalys, utveckling, konstruktion & testning, och kundutvärdering. Var och en av dessa faser består av ett antal olika arbetsmoment. Beroende på projektets storlek varierar antalet arbetsmoment. Vid större projekt finns en del paraplyaktiviteter som till exempel kvalitetsförsäkran och konfigurationshantering. Var och en av de ovanstående faserna är själva itererande. I faserna konstruktion och testning är det en vanlig itererande process att programmeraren gör ändringar för att sedan testa programmet för att se om programmet uppför sig på rätt sätt.

2.2 Allmänt om utvecklingsmiljöer

En utvecklingsmiljö består ofta av ett antal olika delar. Dessa delar kan till exempel vara en editor där programmen skrivs, kompilatorn och länkaren som skapar körbara filer, avlusaren som används för felsökning och som ofta är integrerad med editorn, hjälpfunktioner och bibliotekshanterare. Utöver dessa kan utvecklingsmiljön även innehålla verktyg för att till exempel utforma gränssnitt och skapa databaskopplingar.

Vissa utvecklingsmiljöer innehåller även funktioner för att grafiskt rita upp programmet och skapar sedan kod efter den grafiska representationen.

2.3 Allmänt om kompilatorer

En kompilator är enligt Aho, Sethi och Ullman (1986) ett program som läser in ett program skrivet i ett speciellt språk (källspråk) och översätter denna till ett annat språk (målspråk). Vid översättningen rapporterar kompilatorn eventuella fel i det översatta programmet till användaren.

En kompilator består i huvudsak av åtta olika delar eller faser (Aho, Sethi och Ullman, 1986), och trots att det finns många olika programmeringsspråk så är de flesta kompilatorer uppbyggda på ungefär samma sätt. De åtta faserna besktriver Aho, Sethi och Ullman på följande sätt:

(9)

2 Bakgrund och begrepp

Lexisk analys

Lexisk analys innebär att varje programrad analyseras och alla element identifieras.

Exempel:

position := ursprunglig + förändring * 60

Den ovanstående raden skulle i den lexiska analysen delas upp i sju olika delar.

1. Identifieraren position

2. Tilldelningssymbolen :=

3. Identifieraren ursprunglig

4. Plustecknet

5. Identifieraren förändring

6. Multiplikationstecknet 7. Värdet 60

Syntaxanalys

Detta steg kallas ibland även ”parsing” och innebär att de olika elementen på en rad grupperas hierarkiskt i till exempel ett träd i form av grammatiska fraser som används av kompilatorn. I detta steg kontrolleras så att programmeraren inte har gjort några syntaxfel. Uppdelningen görs efter ett antal förutbestämda regler. Exempelvis så skulle uttrycket ursprunglig + förändring * 60 delas upp i två delar. Dels

ursprunglig och dels förändring * 60. Detta på grund av de aritmetiska reglerna som säger att multiplikation går före addition.

Semantisk analys

Under den semantiska analysen undersöks om källprogramkoden har några semantiska fel. Vidare så samlas information om vilka olika datatyper som används.

Denna information används bland annat för så kallad datatyp-kontroll vilket innebär att en undersökning görs om några otillåtna datatyper används. Exempelvis så är det i en del språk förbjudet att använda variabler av datatypen flyttal vid indexering av listor. Andra saker som undersöks är operationer mellan två olika datatyper som till exempel en addition av ett heltal och ett flyttal. Om en sådan operation inte kan utföras utan extra omvandlingar, så kan kompilatorn se till att lämpliga omvandlingar görs.

Mellanliggande kodgeneration

I denna fas genereras en abstrakt programkod. Syftet med detta är att på ett så bra sätt som möjligt binda ihop de tre första faserna med de två sista. Den abstrakta programkoden bör ha två egenskaper: den ska vara lätt att producera och lätt att översätta till målprogrammet. Genereringen av abstrakt kod kan ske på många olika sätt; ett exempel är ”three-adress code”, där varje minnesadress ses som ett register.

”Three-adress code” är uppbyggt av en sekvens med operationer. Dessa operationer

(10)

2 Bakgrund och begrepp

får maximalt innehålla tre operander. Den tidigare exempelkoden skulle se ut på följande sätt:

temp1 := id3 * 60 temp2 := id2 + temp1 id1 := temp2

Kodoptimering

Kodoptimeringen försöker förbättra koden som genererats i den mellanliggande kodgenerationen, för att få en så snabb kod som möjligt. Även detta kan göras på många olika sätt med olika avancerade algoritmer.

En enkel optimering av ovanstående kod skulle kunna vara:

temp1 := id3 * 60 id1 := id2 + temp1

Vid detta steg måste en avvägning göras. Antingen kan koden optimeras så bra som möjligt vilket tar lång tid och ger snabba och små program eller också kan koden optimeras på ett enklare sätt som går snabbare men resulterar i större och långsammare program.

Kodgenerering

Är den sista fasen i kompileringen. Här översätts den mellanliggande koden till maskinkod eller assemblerkod.

Symboltabell

I symboltabellen lagras information om de identifierare som används i programmet.

Här samlas även olika attribut för identifierarna. De attribut som lagas kan vara minnesadressen till identifieraren, identifierarens typ och var i programmet den gäller.

Om identifieraren är en procedur så lagras procedurens namn, dess argument och typ hos eventuell returvariabel.

Felhanterare

I var och en av de ovan beskrivna faserna kan fel uppstå. Om ett fel uppstår i en av faserna så ska inte kompileringen stanna utan fortsätta så att fel längre fram i programmet kan detekteras. Felhanterarens uppgift är att ta hand om de fel som uppstår och lösa dessa så att kompileringen kan fortsätta.

(11)

2 Bakgrund och begrepp

Bild 2.1: Olika faser i en kompilator

2.4 Programmeringsspråk som ingår i de utvärderade

utvecklingsverktygen

I detta arbete utvärderas utvecklingsverktyg baserade på fem olika programmeringsspråk. I detta avsnitt kommer en kort beskrivning av dessa fem språk.

2.4.1 C/C++

C utvecklades av Bell Laboratories 1972 och användes i början mest som programmeringsspråk för UNIX (som också är skrivet i C) (Houston, 1989). Numera har C flyttats till ett antal olika maskiner och finns nu till de flesta olika plattformar, från små så kallade en-chipsdatorer till stordatorer.

C använder en två-pass kompilator. Med detta menas att kompilatorn gör två genomgångar av programkoden. Vid den första översätts alla funktionsnamn, variabler och anrop till minnesadresser som används vid det andra passet. Fördelen med detta är till exempel att en funktion eller variabel som anropas inte behöver vara deklarerad tidigare i koden utan kan vara deklarerad efter den punkt där den anropas.

C++ är en vidareutveckling av C och utvecklades av Bjarne Stroustrup på AT&T Laboratories i början av 1980-talet. C++ skiljer sig ifrån C på tre viktiga punkter (Lippman, 1995):

1. Stöd för att skapa och använda dataabstraktioner

Lexisk analys

Syntaxanalys

Semantisk analys

Mellanliggande kod- generation

Kodoptimerare

Kodgenerator

Felhanterare Symboltabell

hanterare

Källprogram

Målprogram

(12)

2 Bakgrund och begrepp

2. Stöd för objektorienterad design och programmering 3. Förbättringar av många av de befintliga C-funktionerna

Trots detta behöll C++ många av de fördelar som fanns i C, som snabb exekvering och stor uttryckbarhet (Lippman, 1995). Även C++ finns portat till många olika plattformar och är numera också standardiserad av ANSI-kommittén (ANSI C++).

C/C++ är ett av de mest använda språken och används för att utveckla många olika typer av applikationer. Det finns en mängd färdiga komponenter och bibliotek att köpa ifrån tredjepartstillverkare.

2.4.2 Pascal

Pascal utvecklades av Nicklaus Wirth 1971 (Koffman, 1985). Syntaxen är relativt enkel att lära sig och programkoden är lätt att läsa och förstå, varför Pascal ofta används som programmeringsspråk vid programmeringskurser. Pascal är nu en ISO/ANSI-standard och det som skiljer Pascal-kompilatorer mest ifrån de som finns för C/C++ är att de är ”single pass”. ”Single pass” innebär att kompilatorn bara går igenom koden en gång. Detta medför att alla funktioner och variabler som används måste vara deklarerade tidigare i koden. Dessutom har Pascal hårdare ”typning” än C/C++. Med hårdare typning menas bland annat att omvandlingar mellan olika datatyper inte sker implicit som i C/C++ utan måste utföras explicit av programmeraren.

2.4.3 Java

Java är utvecklat av Sun Microsystems och var från början tänkt att användas som ett plattformsoberoende operativsystem för hemelektronik (Cohn, 1996).

Idag består Java av två delar. En del är själva programmeringsspråket och en del är programkörningsmiljön. Java skiljer sig ifrån traditionella programmeringsspråk som C++ och Pascal på det sättet att istället för att generera maskinkod för en speciell plattform så genererar Java en så kallad ”byte-kod” som kan interpreteras på vilken plattform som helst förutsatt att det finns en så kallad virtuell Javamaskin (Java Virtual Machine).

Med kod som interpreteras menas att koden inte kompileras till maskinkod vid utvecklingsarbetet utan tolkas av en programtolk varje gång programmet körs.

Syntaxen hos Java påminner om den som finns i C++ och har en del funktioner som inte finns i C++. Till exempel har Java automatisk minneshantering och support för multitrådade applikationer på språknivå (Cohn, 1996). Java är ett rent objektorienterat programmeringspråk och är enligt Cohn i många avseenden lättare att använda än C++ då det saknar multipla arv, pekare och goto-satser.

Eftersom Java är ett interpreterande språk så är prestandan beroende av hur bra implementationen av den virtuella Javamaskinen är.

Java är starkt på frammarsch inom många olika applikationsområden, även när det gäller PLC-system där speciella varianter för inbäddade och realtidssystem håller på

(13)

2 Bakgrund och begrepp

att utvecklas. I denna undersökning kommer dock inte någon av dessa varianter att undersökas på grund av att de fortfarande är under utveckling. Det som gör Java speciellt intressant i detta arbete är för att se hur det står sig i prestandatesterna gentemot C/C++ och Pascal.

2.4.4 Ada/Ada95

Ada är ett hårt ”typat”, modulärt uppbyggt programmeringsspråk som påminner om Pascal och Modula (Burns, 1985). Ada utvecklades för den amerikanska militären där det användes som standardspråk för i stort sett all programmering. Ada är designat för att skapa feltoleranta program och innehåller funktioner för undantagshantering och modularitet.

Den första ANSI-standarden för Ada kom 1983 och 1995 kom nästa standard, Ada95, som bland annat innehåller stöd för objektorientering och trådhantering (Kempe, 1996).

2.4.5 Perl

Perl står för ”Practical Extraction Report Language” och utvecklades 1986 av Larry Wall som ville underlätta bearbetning av textfiler på UNIX (Husain, 1996). Perl är ett interpreterande programmeringsspråk som syntaxmässigt påminner om C. Perl innehåller bland annat mönstermatchning, modularisering, objektorientering och POSIX-kompatibilitet (Husain, 1996). Perl används i detta arbete för att se om ett skriptspråk med interpreterande kod, prestandamässigt går att använda i PLC-system.

Interpreterande kod är intressant i ett PLC-system då det skulle vara möjligt att ändra i programkoden direkt i minnet på PLC-systemet, vilket eliminerar nerladdningstiden av programmet ifrån värddatorn där programmen skrivs till måldatorn där programmen körs.

2.5 Realtidssystem

Ett realtidssystem är ett system som reagerar på en utomstående signal inom en förbestämd tid (Burns och Wellings, 1997), och kan delas upp i två grupper: hårda och mjuka realtidssystem.

Ett hårt realtidssystem måste garantera att de tidskrav som är uppsatta hålls. Exempel på ett hårt realtidssystem är styrsystem i flygplan och om dessa inte håller tidskraven kan det resultera i en katastrof.

I mjuka realtidssystem är tidskraven viktiga men systemet fungerar även om de inte uppfylls. Exempel på ett mjukt realtidssystem är bankomater som i värsta fall kan låta kunden vänta en längre tid på att få ut sina pengar. Enligt Burns och Wellings är många realtidssystem både hårda och mjuka, det vill säga de har mjuka tidskrav som ibland kan överskridas och hårda tidskrav som inte får överskridas.

(14)

2 Bakgrund och begrepp

2.6 PLC-system

PLC står för ”Programable Logic Controller”, och är ett programmerbart styrsystem som används till många olika applikationer. Ett PLC-system är uppbyggt kring en central processor, in/ut-gränssnitt och ett minne. Själva styrprogrammet ligger i ett minne som kan programmeras av användaren. Detta styrprogram innehåller funktioner för in/ut-hantering, aritmetiska operationer och reglering.

Till in/ut-gränssnittet kopplas bland annat olika sensorer som läser in data ifrån omvärlden. Beroende på vilken data som kommer in utför systemet olika uppgifter.

I ett PLC-system läggs liten vikt på presentation av information till användaren då de flesta PLC-system saknar någon typ av bildskärm. PLC-system utför i allmänhet ingen eller mycket liten filhantering och saknar i många fall hårddiskar. Programvaran ligger ofta i ett ROM, (Read Only Memory) vilket gör att laddningstider blir mycket korta jämfört med ett hårddiskbaserat system. PLC-system utför ofta någon typ av datainsamling, exempelvis ifrån sensorer, den insamlade datan bearbetas och sedan skapas ofta någon typ av utdata. Insamlingen och bearbetningen av data sker ofta periodiskt, men ett PLC-system kan även arbeta avbrottsstyrt. Programmering av ett PLC-system sker ibland bara vid utvecklingen men ofta så måste programändringar göras även när systemet är installerat. Ett exempel på en applikation för ett PLC- system är ett system som styr en svetsrobot.

Beroende på hur omgivningen ser ut så kan ett PLC-system både vara ett hårt och mjukt realtidssystem. Vissa PLC-system använder sig inte av några signaler från omgivningen och räknas därför inte som realtidssystem.

(15)

3 Problemprecisering

3 Problemprecisering

I detta avsnitt formuleras själva problemet och vissa avgränsningar identifieras.

3.1 Problemformulering

Vid utvärdering av utvecklingsverktyg för realtidssystem finns det ett stort antal aspekter att ta hänsyn till. Dessa aspekter är vid kompilering, prestanda vid exekvering av den kompilerade koden, kostnad vid inköp och vid utbildning av personal, kvalité på dokumentation, support från tillverkaren, avlusningsfunktioner, medföljande funktionsbibliotek och kvalité på medföljande verktyg (till exempel för att rita gränssnitt).

I detta arbete utvärderas ett antal utvecklingsverktyg för PLC-system baserade på fem olika språk (C/C++, Pascal, Java, Ada och Perl) utifrån både kvantitativa och kvalitativa kriterier. Exempel på kvantitativa kriterier är effektivitet som kan mätas i kompileringshastighet, kodeffektivitet, funktionalitet och inköpskostnad. Kvalitativa kriterier kan vara användarvänlighet, kvalité på dokumentation och support från tillverkaren.

3.1.1 Kvantitativa kriterier

Enligt Weiderman (1989) är det som karaktäriserar kvantitativa kriterier att de ofta kan kontrolleras med någon typ av test. De tester som används för att mäta prestanda kallas för benchmarktester. Ett exempel på ett prestandakriterium är kompileringshastighet, vilken går att mäta genom att kompilera olika testprogram under utvecklingsverktygen.

Det finns dock enligt Weiderman en hel del nackdelar med benchmarks, de påverkas av många olika variabler vilket gör det svårt att få exakta mätningar utan att göra en avancerad analys av systemet som testerna körs på. Det är inte bara själva systemet som påverkar resultaten av tester. Beroende på vilka inställningar som görs i utvecklingsverktyget kan till exempel kompileringshastigheten ändras drastiskt.

Vidare säger Weiderman att en annan svår avvägning när det gäller konstruktion av benchmarks är att skriva själva testprogrammen. Hur ska valet av vilka funktioner som ska utföras göras? Mer om dessa problem kommer att tas upp senare i detta arbete.

3.1.2 Kvalitativa kriterier

Till kvalitativa kriterier hör kriterier som är svåra att mäta med hjälp av testning (Weiderman, 1989). Ett exempel på ett kvalitativt kriterium är användarvänlighet, alltså hur lätt det är att lära sig att behärska och använda ett utvecklingsverktyg.

Denna typen av kriterium påverkas mycket av bakgrund och erfarenhet hos användaren.

De flesta kvalitativa kriterier kan enligt Weiderman utvärderas genom att sätta upp ett antal checklistor där olika kvalitativa kriterier ställs upp i form av ja/nej-frågor. Till exempel: Stödjer utvecklingsverktyget några avlusningsfunktioner? Det är sedan

(16)

3 Problemprecisering

relativt enkelt att undersöka de olika kriterierna. Det är enligt Weiderman alltid en avvägning mellan att använda ja/nej-frågor och mer subjektiva frågor. I många fall så räcker dock enligt Weiderman, ja/nej-frågorna långt när en bedömning ska göras.

3.1.3 Undersökningskriterier

Weiderman (1989, s.25) räknar upp ett antal kriterier som är intressanta vid utvärdering av Ada-kompilatorer och vissa av dessa kriterier är även applicerbara på andra typer av kompilatorer.

Bland de kriterier som Weiderman satt upp betraktas följande som relevanta för detta arbete:

• effektivitet hos genererad kod

• kompileringshastighet

• storlek på kompilerad kod

• kodportabilitet

• utbud av färdiga komponenter (bibliotek, arkiv, paket, klasser)

• support och ”recompilation avoidance” (Undvikande av omkompilering av hela programmet vid små ändringar).

Andra kriterier som är intressanta i ett utvecklingsverktyg är bland annat:

• avlusningsfunktioner

• integration mellan de olika delarna i utvecklingsmiljön

• kopplingar till andra komponenter som exempelvis databaser.

De tre första kriterierna är kvantitativa och de övriga kvalitativa. Bland dessa kriterier kommer de fem första att undersökas.

En utförligare förklaring och motivering av var och ett av kriterierna återfinns i kapitel 4.3.

3.1.4 Val av programmeringsspråk för undersökningen

De programmeringsspråk som kommer att vara med i detta arbete är följande:

• C/C++

• Pascal

• Java

• Ada

• Perl.

(17)

3 Problemprecisering

3.2 Avgränsning

På grund av den begränsade tiden för arbetet, så kommer vissa avgränsningar att göras rörande vilka kriterier som skall undersökas och vilka utvecklingsverktyg som kommer att vara med i undersökningen. Det applikationsområde utvärderingen riktar sig mot är begränsat till utveckling av styrprogram för PLC-system och alla tester kommer att göras med avseende på denna typ av system.

De utvecklingsverktyg som kommer att utvärderas är följande:

Microsoft Visual C++ v6.0: Anledningen till att använda Microsofts utvecklingsverktyg i detta arbete är att det är den ledande utvecklingsverktyget för PC-baserade program idag.

Borland Delphi v4.0 (Pascal): Innehåller en ”Single pass”-kompilator. Delphi är ett populärt utvecklingsverktyg för många olika typer av applikationer.

Mircosoft Visual J++ v1.1: Visual J++ är en av de större kommersiella utvecklingsverktygen för Java. Det har är en mer komplett utvecklingsmiljö jämfört med Suns JDK (Java Development Kit) och fanns tillgängligt för detta arbete.

AdaIDE v2.5 for GNAT 3.09 (Ada 95): AdaIDE är ett utvecklingsverktyg som använder GNAT för att generera C-kod av Ada-kod. GCC (Gnu C Compiler) används sedan för kompilering.

Active Perl 5.15 med Perl Development Kit 1.14: Ett utvecklingsverktyg för Perl.

Förutom dessa finns det ytterligare ett antal utvecklingsverktyg/programmeringsspråk som hade varit intressanta att ta med i utvärderingen. Bland dessa finns till exempel Diabs realtidskompilator för C (Diab Data). Anledningen till att inga realtidskompilatorer för C är med i utvärderingen är att de som finns tillgängliga för detta arbete inte kan köras under Windows utan bara under Solaris på Sun-hårdvara.

Vissa av utvärderingskriterierna är svåra att jämföra om alla tester inte körs med samma förutsättningar. Vidare skulle det vara intressant att undersöka hur ett utvecklingsverktyg baserat på assembler hade stått sig mot utvecklingsverktyg baserade på högnivåspråk. Anledningen till att ingen assembler finns med är på grund av att assembler saknar många av de funktioner som finns i ”modernare”

programmeringsspråk, till exempel funktioner med parameterlistor och abstrakta datatyper. Assembler används inte heller i större utsträckning när det gäller större system. När det gäller utvecklingsverktyg för C/C++ (ej med realtidskompilatorer) så finns många att välja mellan från olika tillverkare. Om en begränsning görs till att använda Windows95/98/NT så finns det fortfarande många att tillgå. Bland de som inte kommer att undersökas är Borland C++ Builder och Watcom C++, vilka är två av de större utvecklingsverktygen för C++. Anledningen till att dessa inte undersöks är dels att de inte finns tillgängliga för detta arbete och dels för att tiden är begränsad.

(18)

3 Problemprecisering

Förutom dessa så finns det ett antal andra programmeringsspråk som kunde vara intressanta att ha med i jämförelsen. Bland dessa finns Modula, Basic och Fortran.

Dessa valdes bort på grund av att de sällan används för realtidssystem idag.

(19)

4 Metoder

4 Metoder

De flesta metoderna i en utvärdering går ut på att samla in information om det som skall utvärderas. Information kan inhämtas på flera olika sätt. Patel och Davidson (1994) beskriver ett antal tekniker som ofta används för att samla information om en frågeställning. Informationen kan fås via befintliga dokument, test och prov, olika typer av självrapporteringar, observationer, enkäter, intervjuer och attitydskalor.

De informationskällorna som är mest relevanta för detta arbete är:

• befintliga dokument: böcker, tekniska rapporter, information ifrån tillverkaren etc.

• egna tester

• enkäter och intervjuer av de som arbetar med det som skall utvärderas.

I detta arbete används de tre ovanstående informationskällorna för att samla in information. Den insamlade informationen används för att utvärdera två typer av kriterier:

Kvantitativa kriterier: Vid utvärdering av kvantitativa kriterier är olika tester en bra metod. Det är en fördel om testerna görs med avseende på den typ av uppgift systemet är tänkt att utföra. Detta är dock inte alltid möjligt då sådana tester ibland blir väldigt omfattande.

Kvalitativa kriterier: När kvalitativa kriterier skall undersökas är det viktigt att resultatet inte blir alltför subjektivt, vilket kan vara fallet vid för detaljerade frågor. Den som utvärderar ett kriterium kan med sina egna åsikter påverka resultatet, både positivt och negativt.

4.1 Jämförelse av metoder

Här utvärderas de olika metoderna för informationsinhämtning för att se vilka som passar bäst för att utvärdera kvantitativa och kvalitativa kriterier.

4.1.1 Kvantitativa kriterier

Befintliga dokument: Det finns ofta mycket information att hämta från befintliga dokument. När det gäller benchmarks så kan information fås både från tillverkaren och från användare. Dock finns det en del problem med benchmarks. För att exempelvis utvärdera hastigheten hos en kompilator behövs ett mått på snabbhet (Weiderman, 1989). Många tillverkare använder ”rader kod per minut” som mått.

Detta mått är inte speciellt bra definierat och är väldigt beroende av de givna förutsättningarna. Bland de faktorer som påverkar resultatet finns:

• maskinen och operativsystemet testen körts på

• vilka parametrar kompilatorn har fått (till exempel för optimering och avlusning)

• antalet kommentarer och tomma rader

• definitionen på en ”rad kod” (vanligtvis brukar en rad räknas för varje radmatningstecken som finns i programkoden)

(20)

4 Metoder

• storleken på programmet som kompileras (små program har ofta lägre ”rader kod per minut” än stora program)

• definition av tid (en vanlig klocka räknar med I/O-fördröjningar medan CPU-tid inte alltid gör det).

Om hänsyn tas till detta så är benchmarkresultat från tillverkare inte speciellt relevanta i en jämförelse mellan olika programmeringsspråk och kompilatorer. För att en relevant jämförelse ska kunna göras så måste alla tester göras med samma förutsättningar, vilket inte är troligt då många tillverkare anpassar förutsättningarna så att deras produkter ger så bra resultat som möjligt. Samma problem finns med resultat från utomstående tester på en viss kompilator. Att använda befintlig information från prestandatester är alltså ingen bra metod i detta arbete.

Egna tester: Fördelarna med att göra egna tester är att samma förutsättningar kan ges för alla utvecklingsverktyg som testas. Resultatet blir därför mer rättvist än information från tillverkare och användare. När testfall skapas är det många faktorer som måste tas med, både när det gäller plattformen testet skall göras på och själva testprogrammen. De faktorer som kan påverka resultatet är bland annat (Weiderman, 1989):

• Processorn: Beroende på hur processorn är uppbyggd påverkas testresultat på olika sätt. De delar i processorn som påverkar resultatet är bland annat cacheminne, pipelines, register, klockfrekvens, minneshantering, bredd på bussar, intern arkitektur, interrupt och upplösningen på klockgeneratorn.

• Operativsystemet: De faktorer i operativsystemet som påverkar tester är bland annat enanvändarsystem kontra fleranvändarsystem, en eller flera processer som körs parallellt, minneshantering och filsystem, schemaläggning i multiprocess system, olika typer av systemprocesser och ”garbage collection”.

• Minne: Faktorer här som kan påverka resultaten är cacheminne, bandbredd till processorn, bredd på minnesbussen, klockfrekvens på minnesbussen, periferienheter som ”stjäl” minnesklockcyklar och grad av minnesfragmentering.

• Arkitektur: Hur datorn är uppbyggd, hur många processorer datorn har och vilka databussar som finns och hur de används.

• Tidmätning: Hur tiden mäts och vilken noggrannhet som används.

• Kompilering: Vid kompilering kan till exempel vald grad av optimering påverka resultatet på benchmarks.

Många av dessa faktorer påverkar resultatet av testerna i detta arbete. För att få så rättvisa tester som möjligt vidtas vissa åtgärder för att eliminera påverkan från så många som möjligt av ovanstående faktorer. Mer information om dessa åtgärder finns i kapitel 5.1.

Enkäter och intervjuer: Med enkäter och intervjuer finns samma problem som vid information via befintliga dokument. En annan nackdel är att informationen från

(21)

4 Metoder

denna typ av källa ofta är subjektiv. Denna informationskälla är därför inte speciellt intressant för benchmarkresultat och används inte i detta arbete.

4.1.2 Kvalitativa kriterier

Befintliga dokument: Oavsett om de kvalitativa kriterierna är omskrivna på ja/nej- form eller inte, så är befintliga dokument en utmärkt informationskälla för kvalitativa utvärderingar. Både information från tillverkaren och från andra utomstående källor kan användas i en utvärdering.

Egna tester: Egna tester fungera som en informationskälla för kvalitativa kriterier och har samma för och nackdelar som befintliga dokument. I detta arbete har egna tester av kvalitativa kriterier fungera som ett komplement till befintliga dokument.

Enkäter och intervjuer: En bra informationskälla om frågorna ställs på rätt sätt.

Även här finns risk för att svaren blir subjektiva. På grund av den begränsade tidsramen för detta arbete genomförs inga enkäter eller intervjuer.

4.2 Vald metod

De undersökningar som görs i detta arbete kan delas upp i två olika kategorier:

undersökningar av kvantitativa kriterier och undersökningar av kvalitativa kriterier.

För att undersöka de kvantitativa kriterierna har egna tester att gjorts då detta ger den mest rättvisa jämförelsen mellan de olika kompilatorerna och utvecklingsverktygen.

För de kvalitativa kriterierna har en litteraturstudie av befintliga dokument att gjorts.

4.3 Precisering av utvärderingskriterier för undersökningen

De kvantitativa kriterier som utvärderas i detta arbete är följande:

• effektivitet hos genererad kod

• kompileringshastighet

• storlek på kompilerad kod.

Effektivitet hos genererad kod: Med detta menas hur snabbt den genererade maskinkoden eller den interpreterade koden exekveras. Detta är viktigt i ett PLC- system då olika tidskrav ofta är inblandade och ju effektivere koden är desto lättare är det att möta dessa tidskrav.

Effektivitet hos genererad kod har utvärderas genom att ett antal testprogram skrivs och sedan testkörs. Testprogrammen redovisas längre fram.

Kompileringshastighet: Kompileringshastigheten utvärderas i detta arbete genom att kompileringstiden för ett antal testprogram mäts. Kompileringstid innebär hur snabbt kompilatorn kompilerar ett visst program. Mer information om testprogrammen följer längre fram i rapporten.

Vid utveckling av programvara för PLC-system är kompileringshastigheten viktig då många omkompileringar kan behövas när ett system skall anpassas till att fungera enligt specifikationen.

(22)

4 Metoder

Storlek på kompilerad kod: Vid utveckling av program för persondatorer är storleken på den kompilerade programfilen inte speciellt viktig, då de datorer programmen kommer att köras på ofta har stora hårddiskar och ramminne. När det gäller PLC-system är dock både den eventuella hårddisken och ramminnet begränsade, men ofta är detta inget problem då det för det mesta går att utöka dessa minnen. Ännu viktigare är nerladdningstiden, det vill säga den tid det tar att ladda ner ett program ifrån utvecklingsplattformen till målplattformen. Denna nerladdning sker många gånger under utvecklingsarbetet och det är då viktigt att den går så fort som möjligt. Det är alltså positivt om en kompilator skapar så små programfiler som möjligt. Vid testerna av effektiviteten hos den kompilerade koden kommer även storleken på programfilen att mätas. När det gäller Java och Perl behövs det extra filer för att köra programmen, dels en programtolk och dels de bibliotek eller klasser som används. Vid storleksmätningarna kommer även dessa att räknas in.

De två övriga kriterier som kommer att undersökas är kvalitativa och är följande:

• kodportabilitet

• utbud av färdiga komponenter (bibliotek, arkiv, klasser och moduler).

Kodportabilitet: Med kodportabilitet menas dels hur lätt det är att flytta kod ifrån ett utvecklingsverktyg till ett annat och kompilera om den där, och dels hur lätt kod kan flyttas från ett målsystem till ett annat med annorlunda hårdvara. Hur god kodportabilitet ett visst utvecklingsverktyg har är viktigt att tänka på när man utvecklar programvara för PLC-system. Det beror på att målsystemets hårdvara ibland måste bytas ut för att till exempel få ett snabbare system. Om själva programkoden då är lätt att flytta mellan olika hårdvaruplattformar så leder detta till att kostnaden för ett hårdvarubyte kan hållas nere, då stora delar av den gamla programkoden kan användas. Kodportabiliteten undersöks med en subjektiv bedömning av den information som finns tillgänglig på tillverkarens hemsida på Internet samt delvis via egna tester. Alla utvecklingsverktyg bedöms och tilldelats ett av tre olika omdömen:

God kodportabilitet: Koden kan utan några som helst problem eller ändringar användas i ett annat utvecklingsverktyg eller på en annan hårdvara.

Medelgod kodportabilitet: Koden kan med vissa mindre ändringar användas i ett annat utvecklingsverktyg eller på en annan hårdvara.

Dålig kodportabilitet: Koden kan inte utan stora ändringar användas i ett annat utvecklingsverktyg eller på en annan hårdvara.

(23)

4 Metoder

Utbud av färdiga komponenter (bibliotek, arkiv, klasser och moduler): Hur mycket färdiga komponenter som ingår i utvecklingsverktyget och som kan köpas ifrån tredjepartstillverkare. Exempel på färdiga komponenter är funktionsbibliotek för databaskoppling och TCP/IP (nätverksprotokoll). Utbudet av färdiga komponenter görs genom en subjektiv bedömning av information från tillverkaren och olika källor på Internet. Även här används tre olika omdömen. Dessa tre är:

God tillgång till färdiga komponenter: Många typer av färdiga komponenter finns att få tag på, antingen via tredjepartstillverkare eller direkt från tillverkaren.

Medelgod tillgång till färdiga komponenter: Många typer av färdiga komponenter finns att få tag på, antingen via tredjepartstillverkare eller direkt från tillverkaren, dock är utbudet av leverantörer begränsat.

Dålig tillgång till färdiga komponenter: Få färdiga komponenter finns att få tag på, via tredjepartstillverkare eller direkt av tillverkaren.

Tom text för att word inte ska bugga

4.4 Benchmarks

De benchmarktester som används i detta arbete kommer dels från Bolin (1997) och dels från idéer av Weiderman (1989) som vidareutvecklats. Test 1-16 kommer ifrån Bolin (1997). Dessa tester är anpassade till detta arbete. Anpassningen är att i detta arbete körs testprogrammen i en loop ett fast antal gånger, Bolin använder en loop som kör testprogrammen under en bestämd tid. Mätningarna görs med ett fast antal iterationer och tiden mäts med 4DOS (JP Software, 1999). Test 17 bygger på Weidermans förslag till tester av Ada-kompilatorer och test 18 är ett av deltesten i Linpacktesten, (Grace, 1996) som har anpassats för detta arbete.

4.4.1 Språkfunktionstester

Enligt Weiderman (1989) finns det många olika typer av benchmarks. Weiderman beskriver fem olika typer: språkfunktionstester, kapacitetstester, komposittester, symmetriska tester samt applikationsspecifika tester. I detta arbete genomförs bara språkfunktionstester. Det innebär att testerna i detta arbete testar enstaka funktioner var för sig hos ett språk. De funktioner som testas är grundfunktioner. Anledningen till detta är att ett program ofta består av en kombination av dessa funktioner. Denna typ av tester visar svagheter hos olika delar i ett utvecklingsverktyg. Om den programvara som skall utvecklas använder vissa funktioner mycket kan utvecklingsverktyget väljas med stöd av denna typ av tester. Dock är det svårt att få den exakta prestandan utvärderad i denna typ av test. I detta arbete är språkfunktionstest intressanta för att de visar skillnaden i prestanda mellan olika utvecklingsverktyg. De övriga testtyperna ger inte heller ett exakt prestandavärde utan bara ett ungefärligt prestandavärde. Undantaget är applikationsspecifika tester.

Problemet med dessa är att applikationen inte är skriven när utvecklingsverktyg skall väljas.

(24)

4 Metoder

4.4.2 Testfall för kodeffektivitet

1. Loopoverhead: Testerna körs i en loop ett antal gånger. Vid dessa tester är det inte bara själva testfallet som påverkar tiden utan också de anrop som behövs för själva loopen. För att eliminera de fel som kan uppstå körs detta test med en tom loop med fyra olika loopvärden: 100,000; 1,000,000; 10,000,000 och 100,000,000. Resultatet på detta test används för att justera resultaten på de andra testen.

2. Lokal variabeltilldelning: Testar hastigheten vid en lokal variabeltilldelning.

Exempel: n:=i, där i är en ökande 32-bitars lokal heltalsvariabel. Under testet görs 10,000,000 tilldelningar i en loop.

3. Global variabeltilldelning: Testar hastigheten vid en global variabeltilldelning.

Exempel: n:=i, där i är en ökande 32-bitars global heltalsvariabel. Under testet görs 10,000,000 tilldelningar i en loop.

4. Matristilldelning: Testar hastigheten vid tilldelning av värden till olika element i en matris. Matrisen består av fyra heltal som tilldelas stigande heltalsvärden.

Under testet körs en loop 10,000,000 varv där alla fyra elementen tilldelas nya värden på varje varv i loopen.

5. Uppräkning av 8-bitarsvariabel: Detta test räknar upp en 8-bitars teckenlös heltalsvariabel ett antal gånger. Under testet så körs 10,000,000 uppräkningar där varje uppräkning ökar variabeln med 1. Variabeln tillåts ”slå runt” när den nått sitt maxvärde.

6. Uppräkning av 16-bitarsvariabel: Räknar upp en 16-bitars heltalsvariabel med tecken ett antal gånger. Under testet så körs 10,000,000 uppräkningar där varje uppräkning ökar variabeln med 1. Variabeln tillåts ”slå runt” när den nått sitt maxvärde.

7. Uppräkning av 32-bitarsvariabel: Detta test räknar upp en 32-bitars heltalsvariabel med tecken ett antal gånger. Under testet så körs 10,000,000 uppräkningar där varje uppräkning ökar variabeln med 1. Variabeln tillåts ”slå runt” när den nått sitt maxvärde.

8. Uppräkning av 64-bitarsvariabel: Detta test räknar upp en 64-bitars heltalsvariabel med tecken ett antal gånger. Under testet så körs 10,000,000 uppräkningar där varje uppräkning ökar variabeln med 1. Variabeln tillåts ”slå runt” när den nått sitt maxvärde.

9. Uppräkning av 64-bitars flyttalsvariabel: Detta test räknar upp en 64-bitars flyttalsvariabel med tecken ett antal gånger. Under testet så körs 10,000,000 uppräkningar där varje uppräkning ökar variabeln med 1. Variabeln tillåts ”slå runt” när den nått sitt maxvärde.

10. Matrisallokering: Detta test skapar en matris med 4 stycken 32-bitars heltal.

Under testet skapas matrisen 10,000,000 gånger i en loop. De gamla matriserna

(25)

4 Metoder

deallokeras direkt efter att de allokerats för att minnet inte skall ta slut under testen.

11. Funktionsanrop: Detta test anropar en parameterlös funktion som inte innehåller någon kod. Även detta test kommer att utföras 10,000,000 gånger i en loop.

12. Anrop av matematisk funktion 1: Detta test anropar funktionen för absolutvärde på en heltalsvariabel. Under testet körs 10,000,000 anrop av funktionen.

13. Anrop av matematisk funktion 2: Detta test anropar den inbyggda funktionen för cosinus på en 32 bitars flyttalsvariabel. Under testet körs 10,000,000 anrop av funktionen men fyra olika värden: 15.0, 30.0, 45.0 och 60.0.

14. Villkorstest: Detta test utför utvärderingar av villkor. Under testet körs 10,000,000 anrop av en if-else if-else-sats.

15. Strängallokering: Detta test allokerar upp en ny sträng på 50 tecken. Under testet skapas strängen 10,000,000 gånger i en loop. De gamla strängarna deallokeras direkt efter de allokerats för att minnet inte skall ta slut under testen.

16. Typecasting: Detta test gör en ”typecast” på en flyttals- till en heltalsvariabel.

Under testet körs denna ”typecast” 10,000,000 gånger i en loop. Flyttalsvariabeln initieras till värdet 1000.

17. Rekursivt anrop: Detta test gör ett rekursivt anrop som resulterar i 100,000 iterationer.

18. Lintest: Detta test är en del av Linpacktesten (Grace, 1996) och testar hastigheten vid linjära funktioner. I detta arbete beräknas den linjära funktionen:

2/3n^3+2n^2. Detta görs 10,000,000 gånger i en loop. Istället för n^3 och n^2 så används loopräknarvariabeln/10 och loopräknarvariabeln/100 vid uträkningarna.

4.4.3 Testfall för kompileringshastighet

För att testa kompileringshastighet hos de olika utvecklingsverktygen används speciella testprogram. Dessa testprogram består av alla de ovanstående testfallen i ett och samma program där var och ett av testfallen är duplicerade ett antal gånger för att få ett så stort program som möjligt. Anledningen till att de ovanstående testfallen används istället för att skriva ett helt nytt testprogram är att den begränsade tiden för detta arbete inte tillåter att ett helt nytt testprogram utvecklas.

(26)

5 Genomförande

5 Genomförande

I detta avsnitt redovisas resultat av genomförandet av tester och undersökningar. Först redovisas resultatet av de kvantitativa testerna och sedan resultaten av de kvalitativa undersökningarna.

5.1 Förutsättningar för tester

Alla tester i undersökningen körs på en 200 MHz Pentiumdator med 32Mbyte ramminne och 4.3Gbyte IDE hårddisk. Vid testerna används Windows 98 som operativsystem. För tidmätningarna används 4DOS inbyggda tidmätningsfunktioner.

Dessa ger en noggrannhet på en hundradels sekund vilket är betydligt bättre än att använda ett stoppur. Ett bättre alternativ till 4DOS för tidmätning är att i varje testprogram läsa av systemtimern före och efter själva testen. Anledningen till att detta inte gjordes är att de nödvändiga funktionerna för detta inte finns tillgängliga i alla utvecklingsverktyg som testas och att inte finns tid att skapa den nödvändiga funktionaliteten under detta arbete. Ett problemet med att använda 4DOS för tidsmätning är att även programladdning ingår i den uppmätta tiden. För att förhindra att detta påverkar resultatet allt för mycket, så körs alla tester 12 gånger efter varandra där det högsta och lägsta resultatet tas bort och de övriga används för att beräkna ett medelvärde på tiden för testet. Denna metod förhindrar att laddningstiderna påverkar resultatet allt för mycket. Efter den första testkörningen så befinner sig programmet i disk-cachen och laddas mycket fort. Dock är det inte alltid säkert att det första testet tar längst tid. I ett PLC-system är programmets laddningstid inte speciellt intressant då programmen ofta laddas från ett snabbt ROM-minne och inte från en hårddisk.

För att inte datorns cache ska påverka resultatet, har både den interna (i processorn) och den externa cachen i testdatorns varit avstängda. Under testkörningarna finns endast två processer på testdatorn: Explorer och 4DOS. Explorer måste vara igång för att kunna använda Windows och går inte att stänga av. Utöver dessa processer körs testprogrammet och dess eventuella tolk. Vid alla tester är all optimering i kompilatorerna avstängd.

Alla tester kan inte genomföras med alla de fem utvecklingsmiljöerna, till exempel så saknar Perl vissa av de funktioner som krävs för dynamisk minneshantering. I dessa fall anpassas testprogrammen för att köras på ett liknande sätt. Hur denna anpassning gjordes beskrivs i kapitel 5.2.

Vid testkörningar av Javaprogram användes Suns JRE 1.1.8 (Java Run-time Environment) med JIT (Just In Time compilation) påslaget. JIT innebär att delar av Javakoden kompileras till maskinkod vid exekvering i tolken.

(27)

5 Genomförande

5.2 Effektivitet hos genererad kod

I dessa tester har 18 olika testprogram körts på var och ett av utvecklingsverktygen.

Vissa av testerna har inte kunnat genomföras på alla verktygen på grund av att några av verktygen saknar vissa av de funktioner som används i testerna.

I diagrammen för benchmark 2 till 18 finns två tider. En som kallas totaltid och är den uppmätta tiden för testet. Den andra tiden kallas för omräknad tid och består av totaltiden med loopoverheaden bortdragen.

5.2.1 Loop overhead

Kör en tom loop mellan 10^5 och 10^8 gånger.

GNAT, Visual C++, J++ och Delphi har jämförbara prestanda i loopoverheadtesten.

Värdena ifrån testerna med Active Perl är så höga att de inte kommer att redovisas i diagramform i resten av testerna, detta för att resultaten från de fyra första utvecklingsverktygen skall synas bättre.

Loop overhead - Loopvärde: 10^5 - 10^8

1 10 100 1000

sekunder 10^5

10^6 10^7 10^8

10^5 1,852 0,7012 7,675 0,835 11,246

10^6 3,746 2,169 8,209 1,306 94,019

10^7 20,737 13,603 13,546 6,463 922,107

10^8 187,789 125,535 66,87 52,198 9184,32

GNAT (Ada) Microsoft Visual

C++ Mircosoft J++ Borland Delphi Active Perl

(28)

5 Genomförande

5.2.2 Lokal variabeltilldelning

Testar exekveringstiden vid tilldelning av värde till en lokal variabel.

5.2.3 Global variabeltilldelning

Testar exekveringstiden vid tilldelning av värde till en global variabel.

Lokal variabeltilldelning - Loopvärde: 10^7

0,00 10,00 20,00 30,00 40,00 50,00 60,00 70,00 80,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 30,79 30,94 66,86 19,16

Omr. tid (sek) 10,06 17,34 53,31 6,49

GNAT (Ada) Visual C++ MS J++ Borland Delphi

1359,63 Active Perl

437,53

Global variabeltilldelning - Loopvärde: 10^7

0,00 10,00 20,00 30,00 40,00 50,00 60,00 70,00 80,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 29,80 20,85 66,87 17,25

Omr. tid (sek) 9,06 7,25 53,32 4,58

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

1358,44 436,33

(29)

5 Genomförande

5.2.4 Matristilldelning

Tilldelar värden till olika element i en matris.

5.2.5 Uppräkning av 8-bitarsvariabel

Räknar upp en 8-bitarsvariabel och låter den ”slå runt” vid maxvärde.

I Perl finns bara en enda variabeltyp som kan innehålla allt ifrån heltal och flyttal till strängar. Perl finns med i alla av de fem uppräkningstesterna. Dock så används

Matristilldelning - Loopvärde: 10^7

0,00 20,00 40,00 60,00 80,00 100,00 120,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 41,57 35,75 103,06 33,04

Omr. tid (sek) 20,83 22,15 89,51 20,37

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

6083,47 5161,37

Uppräkning av 8-bitarsvariabel - Loopvärde: 10^7

0,00 10,00 20,00 30,00 40,00 50,00 60,00 70,00 80,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 29,08 21,02 66,83 16,35

Omr. tid (sek) 8,35 7,42 53,29 3,67

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

1136,22 214,12

(30)

5 Genomförande

samma testprogram till alla heltalsuppräkningstesterna. Till flyttalsuppräkningen används en lite modifierad version. Mer om detta i avsnitt 5.2.9.

5.2.6 Uppräkning av 16-bitarsvariabel

Räknar upp en 16-bitarsvariabel och låter den ”slå runt” vid maxvärde.

Testprogrammet för Perl är samma som vid uppräkning av 8-bitarsvariabel.

5.2.7 Uppräkning av 32-bitarsvariabel

Räknar upp en 32-bitarsvariabel och låter den ”slå runt” vid maxvärde.

Uppräkning av 16-bitarsvariabel - Loopvärde 10^7

0,00 10,00 20,00 30,00 40,00 50,00 60,00 70,00 80,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 31,20 21,98 66,85 16,33

Omr. tid (sek) 10,46 8,38 53,31 3,66

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

1136,22 214,12

Uppräkning av 32-bitarsvariabel - Loopvärde: 10^7

0,00 10,00 20,00 30,00 40,00 50,00 60,00 70,00 80,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 29,93 21,02 66,92 16,36

Omr. tid (sek) 9,19 7,41 53,37 3,69

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

1136,22 214,12

(31)

5 Genomförande

Testprogrammet för Perl är samma som vid uppräkning av 8-bitarsvariabel.

5.2.8 Uppräkning av 64-bitarsvariabel

Räknar upp en 64-bitarsvariabel och låter den ”slå runt” vid maxvärde.

Testprogrammet för Perl är samma som vid uppräkning av 8-bitarsvariabel.

5.2.9 Uppräkning av 64-bitars flyttalsvariabel

Räknar upp en 64-bitars flyttalsvariabel och låter den ”slå runt” vid maxvärde.

Uppräkning av 64-bitarsvariabel - Loopvärde: 10^7

0,00 10,00 20,00 30,00 40,00 50,00 60,00 70,00 80,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 62,01 21,07 66,86 24,50

Omr. tid (sek) 41,27 7,46 53,32 11,83

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

1136,22 214,12

Uppräkning av 64-bitars flyttalsvariabel - Loopvärde: 10^7

0,00 10,00 20,00 30,00 40,00 50,00 60,00 70,00 80,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 29,21 23,95 66,88 20,20

Omr. tid (sek) 8,48 10,34 53,33 7,53

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

1184,21 262,11

(32)

5 Genomförande

Testprogrammet för Perl är samma som används vid uppräkning av 8-bitarsvariabel med en modifikation så att uppräkningsvariabeln initieras till ett flyttal och inte ett heltal.

5.2.10 Matrisallokering

Allokerar upp en matris med fyra 32-bitars heltalsvärden. Matrisen deallokeras i varje varv i loopen.

Detta test gick inte att genomföra i Perl. Anledningen till detta är att funktioner för dynamisk allokering av variabler inte finns tillgängliga.

Anledningen till att Java kommer så långt efter de övriga i denna test kan bero på att Java automatiskt genomför ”garbage collection”. Deallokering av ett dynamiskt allokerat element sker när alla referenser till det frigörs. I detta fallet frigörs referensen varje varv i loopen vilket kan medföra att den Virtuella Javamaskinen utför en ”garbage collection” vilket skulle förklara resultatet av detta test.

Matrisallokering - Loopvärde: 10^7

0,00 2000,00 4000,00 6000,00 8000,00 10000,00 12000,00 14000,00 16000,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 420,77 896,17 14869,96 427,51

Omr. tid (sek) 400,03 882,57 14856,41 414,84

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

N/A N/A

(33)

5 Genomförande

5.2.11 Funktionsanrop

Anropar en tom, parameterlös funktion.

5.2.12 Anrop av matematisk funktion 1 Beräknar absolutvärdet av –30.

Nämnvärt i denna test är att Visual C++ kommer så långt efter GNAT och Borland Delphi. Detta kan bero på att abs-funktionen är implementerad på ett långsammare sätt än hos GNAT och Borland Delphi.

Funktionsanrop - Loopvärde: 10^7

0,00 10,00 20,00 30,00 40,00 50,00 60,00 70,00 80,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 46,86 36,39 67,16 22,20

Omr. tid (sek) 26,13 22,79 53,61 9,53

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

2710,45 1788,34

Matematisk funktion 1 (abs) - Loopvärde: 10^7

0,00 10,00 20,00 30,00 40,00 50,00 60,00 70,00

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 25,18 36,78 58,79 15,32

Omr. tid (sek) 4,44 23,18 45,25 2,65

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

1319,95 397,85

(34)

5 Genomförande

5.2.13 Anrop av matematisk funktion 2 Beräknar cosinus för 15.0; 30.0; 45.0 och 60.0.

I detta test utfördes fyra deltester där olika värden på cosinus används. I diagrammet finns medelvärdet för dessa fyra testerna.

GNAT får väldigt dåliga testresultat vilket kan bero på en långsam implemenation av cosinusfunktionen. Visual C++ tar dubbelt så lång tid på sig som Java i detta test men skillnaden är inte så stor som mellan GNAT och de övriga. Även detta kan bero på att implementationen av cosinus i Visual C++ inte är lika snabb som den i Java och Borland Delphi.

Matematisk funktion 2 (cos) - Loopvärde: 10^7

0,00 200,00 400,00 600,00 800,00 1000,00 1200,00 1400,00 1600,00 1800,00 2000,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 1753,63 121,63 67,27 36,91

Omr. tid (sek) 1732,89 108,02 53,73 24,24

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

1338,62 416,51

(35)

5 Genomförande

5.2.14 Villkorstest

Utvärderar en ”if-else if-else” selektion.

Anmärkningsvärt i detta test är att Visual C++ får så väldigt bra resultat. Detta kan bero på en bra implementation av selektioner.

5.2.15 Strängallokering

Allokerar upp minne för en 50 tecken lång sträng. Strängen deallokeras vid varje varv i loopen.

Villkorstest - Loopvärde: 10^7

0,00 10,00 20,00 30,00 40,00 50,00 60,00 70,00 80,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 29,64 15,47 67,21 25,51

Omr. tid (sek) 8,91 1,87 53,67 12,84

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

1405,41 483,31

Strängallokering - Loopvärde: 10^7

0,00 5000,00 10000,00 15000,00 20000,00 25000,00 30000,00 35000,00 40000,00

sekunder

Totaltid (sek) Omr. tid (sek)

Totaltid (sek) 425,75 895,28 37050,22 426,89

Omr. tid (sek) 405,02 881,68 37036,67 414,22

GNAT (Ada) Visual C++ MS J++ Borland Delphi Active Perl

N/A N/A

References

Related documents

Detta borde inte vara något problem för en personifiering dock eftersom det går att se alla sidor som besökts, hur besökaren tog sig dit genom referrer

Vill man skapa sin sida med ett annat verktyg, NetObjects Fusion eller kanske Notepad, skall dessa sidor importeras till FrontPage- webben och inte laddas upp direkt till webservern.

Metoden som använts för att bringa klarhet i hur läsarna upplever olika navigeringssätt i elektronisk text har varit en kvalitativ intervju och en kvantitativ effektivitetsmätning

- Vi skulle inte hinna med att kolla upp vad alla gör. Så länge inte ledningen kräver att något sådant görs så kommer vi inte att göra det. Om det kommer att krävas så måste

Hypotesen för det här arbetet var att människor som får vara med i ett utvecklingsarbete får en positivare attityd till systemet och dess information.. Genom den positivare

I de symmetriska algoritmerna ligger inte säkerhet i nycklarna utan i förmågan för att påverka alla bitar i den klartext som skall användas, det vill säga i algoritmen själv.

Olika lösningar för detta finns, till exempel kan en UNIX-maskin agera som en Windows NT-server, Microsoft Windows NT kan användas på en PC-server och Novell NetWare kan användas

Största nackdel som bearbetats fram genom intervjuerna samt litteraturstudierna som även i vissa fall kan vara avgörande för projektet är enlig författaren av rapporten att tekniken