Dette indlæg er alene udtryk for skribentens egen holdning.

Man må godt starte med en for-løkke

14. maj 2014 kl. 08:306
Artiklen er ældre end 30 dage

En af de første ting, man lærer inden for de fleste programmeringssprog, er brugen af if-sætninger og for-løkker. Disse tillader, kort fortalt, respektivt at inkorporere konditionelle udsagn og at gennemløbe indekser i koden, og når man har forstået brugen af disse, kan man hurtigt komme i gang med at skrive de første kodestumper.

Da jeg på mit første studieår lærte at programmere i Matlab, kunne jeg således som en af de første små programmer skrive et "sten-saks-papir"-spil - som udover nogle (pseudo-)tilfældigt genererede tal, bestod af en masse if-sætninger; hvis spiller et har fået sten, og spiller to har fået saks, vinder spiller et, hvis spiller et har fået papir, og spiller to har fået sten, vinder spiller et, osv.

Ligeledes lærte vi, at man nemt tilgår store matricer og deres elementer med for-løkker, hvilket på tilsvarende vis blev brugt til at simulere konkrete systemer, f.eks. vandforurening hvor felterne i matricerne repræsenterede forureningskoncentrationen i en to-dimensionel sø.

Vi lærte dog også snart, at for-løkker ikke er specielt effektive og nemt - i mere praktisk anvendelig kode - kommer til at udgøre en flaskehals for beregningstiden. Dette var i første omgang en Pandoras æske at få åbnet for sine øjne - "skal vi så glemme alt om denne let forståelige og anvendelige teknik, med hvilken vi så nemt regner på matricer?" - men på lidt længere sigt en adgang til at værdsætte, hvor kraftfuld lineær algebra er.

Artiklen fortsætter efter annoncen

Særligt i Matlab - som er kort for, ja, matrix laboratory - er der meget at vinde ved at mestre lineær algebra og ved at vektorisere koden. Selvom det meste af min egen kode er trimmet for for-løkker, var der alligevel lidt at hente, da jeg optimerede større dele af min kode tidligere i år.

Konkret forbedrede jeg implementeringen af en Gram-Schmidt ortonormaliseringsalgoritme, som profiling viste var meget tidskrævende. Ændringen - som vektoriserede én af de involverede for-løkker - var efter en smule tænkearbejde oplagt og gav en kæmpe hastighedsforøgelse.

At jeg ikke i første omgang implementerede den vektoriserede udgave, har i princippet kostet mig en masse tid. Men ofte er det vigtigste at komme igang med kode, som virker, og som man sidenhen kan forbedre og optimere - og til dette formål er for-løkker et uvurderligt værktøj! Som beskrevet ovenfor er de nemme at forstå og implementere, og man kan ved at bruge dem lynhurtigt komme i gang med sine beregninger.

Dermed ikke sagt at man skal glemme alt om matricer og matrixoperationer i den indledende kodefase. Men det er bedre at komme i gang med kodningen og at opnå (måske lidt langsomt) nogle første resultater end at løbe hovedet imod den super effektive kodes mur fra første færd.

Med denne filosofi er jeg de sidste par dage kommet i gang med de tre-dimensionelle optiske simuleringer, jeg i mit ph.d. projekt arbejder med. Billedet i tweetet ovenfor viser feltprofiler af optiske modes i en firkantet bølgeleder (med længdeaksen langs z-aksen, ind i billedets plan).

Artiklen fortsætter efter annoncen

Resultaterne er særdeles præliminære, og koden er absolut ikke optimeret - men at se og visualisere de første resultater er ganske motiverende og stimulerende for det videre arbejde, og de unødvendige for-løkker skal tidsnok blive luet ud.

For man må godt starte med en for-løkke.

6 kommentarer.  Hop til debatten
Debatten
Log ind eller opret en bruger for at deltage i debatten.
settingsDebatindstillinger
6
15. maj 2014 kl. 10:55

Som jeg ser det på eksemplerne på vektorisering fra Matlab, så er forskellen primært at man definerer et array, hvor elementerne svarer til resultatet af en løkke med en efterfølgende tildeling af operation.</p>
<p>Bag kulisserne sker der sikkert det samme, så er det ikke mere et spørgsmål om at Matlabs compiler bare selv har sørget for noget optimering?

Det er en god pointe, og Torben Mogensen forklarede detaljerne yderligere. Dette kan måske være anderledes i andre programmeringssprog, men i Matlab er vektoriseringen i hvert fald optimeret, hvilket er værd at holde sig for øje, hvis man skriver kode deri.

Og i øvrigt, der findes jo også while, og mange if sætninger kan passende erstattes med case.

Sandt, der findes en hel del funktioner, jeg ikke omtalte i blogindlægget:-)

5
15. maj 2014 kl. 10:52

Synes ofte at man kan bruge en let forståelig, men langsom kode til generering af test data til den optimerede kode, som ofte bliver mindre intuitiv at læse (og specielt for andre).

Enig, koden bliver ofte mere knudret og svær at overskue, når man optimerer den og vektoriserer frem for at bruge løkker. Det handler i min optik om at finde den rette balance, hvor koden på den ene side er effektiv og på den anden side er til at overskue.

4
14. maj 2014 kl. 13:34

Bag kulisserne sker der sikkert det samme, så er det ikke mere et spørgsmål om at Matlabs compiler bare selv har sørget for noget optimering?

Det er korrekt, at den primære årsag til at for-løkker er langsomme i Matlab er, at det er et fortolket sprog, så der er en del fortolkningsoverhead, der forsvinder, når man bruger vektoroperationer, der er implementeret med løkker på maskinkodeniveau.

Men selv med oversatte sprog kan det være en fordel at bruge vektoroperationer: De kan ofte bedre paralleliseres end eksplicitte løkker, specielt hvis man vil udnytte grafikprocessorer i beregningen.

2
14. maj 2014 kl. 12:49

Som jeg ser det på eksemplerne på vektorisering fra Matlab, så er forskellen primært at man definerer et array, hvor elementerne svarer til resultatet af en løkke med en efterfølgende tildeling af operation.

Bag kulisserne sker der sikkert det samme, så er det ikke mere et spørgsmål om at Matlabs compiler bare selv har sørget for noget optimering?

Og i øvrigt, der findes jo også while, og mange if sætninger kan passende erstattes med case.

1
14. maj 2014 kl. 09:01

Synes ofte at man kan bruge en let forståelig, men langsom kode til generering af test data til den optimerede kode, som ofte bliver mindre intuitiv at læse (og specielt for andre).