</motto<
/null/vskip5truecm
         -- -- V{is{l{: Vektorianalyysi
>>

/chapter</ii<Vektorilaskenta>>
 
Ajatellaanpa esimerkin vuoksi, ett{ kahden liukuluvun $a$ ja $b$
kertolasku tapahtuu seuraavissa vaiheissa:
 
1) Normita $a$/nl
2) Normita $b$/nl
3) Kerro $a$:n ja $b$:n mantissat kesken{{n/nl
4) Laske yhteen $a$:n ja $b$:n eksponenttiosat/nl
5) Normita lopputulos/nl
/null
 
Jos jokainen vaihe vie yhden kellojakson ja vaiheita on $k$
(kuvitteellisessa esimerkiss{mme $k=5$),
kest{{ kertolasku $k$ kellojaksoa.  Jos jakson pituus on
$/tau$, pystyt{{n yhdess{ sekunnissa laskemaan $1//k/tau$
kertolaskua.  Kahden $N$:n mittaisen vektorin kertominen
kesken{{n vie silloin aikaa $Nk/tau$ sekuntia. 

    
Tarkastellaan esimerkkin{ seuraavan </sc fortran>-silmukan suoritusta:
 
</copymode
      do 1 i=1,n
         c(i)=a(i)*b(i)
   1  continue
>
 
Jos prosessori on jaettu siten, ett{ edell{ mainitun viiden
vaiheen suoritukset ovat toisistaan riippumattomia, voimme
aloittaa joka kellojaksolla uuden lukuparin k{sittelyn.  Kun
ensimm{isten alkioiden k{sittely siirtyy vaiheeseen 2,
aloitetaan samalla toiselle alkioparille vaihe 1.  Seuraava
kuva esitt{{ laskutoimitusten etenemist{
kertolaskuyksik|ss{:
 
/page/null/vskip8truecm
 
Ensimm{inen tulos valmistuu edelleenkin vasta $k/tau$:n 
(esimerkiss{mme 5 kellojakson) kuluttua,
mutta t{m{n j{lkeen saadaan uusi tulos joka kellojaksolla. T{llaisella
laskutoimituksen osien /ii<limityksell{> eli
</sl/ii<liukuhihnoituksella>> (/ii<pipelining>) saavutettava teho l{henee
$1///tau$ tulosta sekunnissa vektorin pituuden kasvaessa. $N$:n
mittaisten vektorien kertolaskuun tarvitaan en{{ $N/tau$ sekuntia.
 
Nykyisten supertietokoneiden ja er{iden tehokkaimpien ty|asemien
prosessorit ovat </sl/ii<vektoriprosessoreja>>, joiden toiminta
perustuu juuri t{llaiseen liukuhihnoitukseen. Vektoriprosessori
</bf ei> laske kahden vektorin kaikkia alkioita yhteen 
samanaikaisesti, vaan limitetysti. 
 
Laskettaessa esimerkiksi lauseketta $(a+b)*c$
skalaarikoneella lasketaan ensin $a+b$, talletetaan johonkin
rekisteriin ja kerrotaan sitten $c$:ll{.  Jos prosessori
sis{lt{{ erilliset yksik|t yhteen- ja kertolaskua varten, ei
summaa tarvitse tallettaa minnek{{n, vaan se voidaan sy|tt{{
suoraan kertolaskuyksikk||n.  Jos molemmat yksik|t ovat
liukuhihnoitettuja, ensimm{isen summan valmistuttua siirtyy
jokaisella kellojaksolla yksi uusi lukupari
kertolaskuyksikk||n.  Kun my|s ensimm{inen tulo on laskettu,
saadaan jokaisella seuraavalla kellojaksolla yksi summa ja
yksi tulo.  T{m{n </sl/ii<ketjutuksen>> (/ii<chaining>)
ansiosta aikayksik|ss{ valmistuvien liukulukuoperaatioiden
m{{r{ voi kasvaa l{hes $p$-kertaiseksi, jos prosessorissa on
$p$ erillist{ liukulukuyksikk|{. 
 
Edell{ mainitut arvot ovat teoreettisia huipputehoja.
Saavutettava huipputeho riippuu hyvin paljon siit{, kuinka
tehokkaasti ohjelma osaa k{ytt{{ hyv{kseen prosessorin tarjoamia
mahdollisuuksia. Todellisuudessa v{lill{ joudutaan aina tekem{{n
yksitt{isi{ vektorilaskutoimituksia ja skalaarioperaatioita, joten
huipputehoa ei k{yt{nn|ss{ pystyt{ saavuttamaan kuin hetkellisesti.

Tarkastellaan ohjelmaa, jonka
skalaariversion kuluttama CPU-aika on $T$ ja siit{
osa $S$ kuluu skalaarikoodissa ja $V$ koodissa,
joka voitaisiin vektoroida ($S+V=T$).
Jos vektorointi nopeuttaa suoritusta $n$-kertaisesti,
on vektoroidun ohjelman suoritukseen kuluva aika $S+V//n$,
joten saavutettava nopeuden lis{ys on 

$$s=<S+V/over S+V//n>.$$
 
T{m{ tunnetaan </sl/ii<Amdahlin laki>na>. Seuraava kuva
esitt{{ suorituskyvyn lis{yst{ vektorikoodin osuuden
$V//T$ funktiona, kun $n$ on Craylle tyypillinen 10.

/null/vskip10truecm

T{rkein havainto t{st{ on, ett{ hidas skalaarikoodi
dominoi suoritusaikaa, ellei vektoroituvuusaste
ole huomattavan korkea. 
 
/section</ii<Vektoroituvat silmukat>>
 
Crayn </sc fortran>-k{{nt{j{ tuottaa vektoroitua koodia
vain sisimmist{ silmukoista, jotka voivat olla
joko </tt do> -silmukoita tai joskus my|s </tt goto> -rakenteita.
Silmukan t{ytyy lis{ksi toteuttaa koko joukko erilaisia
ehtoja, joita tarkastelemme seuraavassa. Aluksi kuitenkin
muutamia m{{ritelmi{.
 
</sl/ii<Tilap{inen skalaari>> (/ii<scalar temporary>) on yksinkertainen
muuttuja, jonka arvo lasketaan silmukassa ennen kuin sit{
k{ytet{{n. T{llaiset muuttujat voitaisiin periaatteessa
eliminoida kirjoittamalla kaikki lausekkeet kokonaan auki.
Esimerkiksi seuraavassa </tt s> on tilap{inen skalaari.
 
</copymode
      do 1 i=1,n
         s=a(i)+b(i)
         x(i)=s
         y(i)=sqrt(s)
    1 continue
>
 
</sl/ii<Invariantti>> on lauseke, jonka arvo
ei muutu silmukassa. Mik{{n invariantissa lausekkeessa
esiintyv{ muuttuja ei saa esiinty{ sijoituslauseen 
vasemmalla puolella eik{ aliohjelman tai funktion
parametrina (lukuunottamatta intrinsic-funktioita
ja lausefunktioita), koska aliohjelma voi muuttaa sit{.
 
</sl Silmukan /ii<induktiomuuttuja>> (/ii<loop induction variable>) on
muuttuja, jonka arvoa lis{t{{n tai v{hennet{{n kokonaislukuarvoisella
invariantilla (kokonaislukuvakiolla) joka kierroksella.  Se on siis
muotoa $a+i*b$, miss{ $a$ ja $b$ ovat vakioita ja $i$ silmukan
kierroslaskuri.  Triviaali esimerkki induktiomuuttujasta on </tt do>
-lauseen silmukkaindeksi.  

Seuraavassa esimerkiss{ </tt i>, </tt j>
ja </tt k> ovat induktiomuuttujia, mutta </tt l> ei ole, koska sen
lis{ys ei ole invariantti.
 
</copymode
      do 1 i=1,n
         j=i+1
         k=n-j
         l=2*l
         a(i)=b(j)+c(k)
         ...
    1 continue
>
 
</sl/ii<Vektoriviittaus>> (/ii<vector array reference>) on taulukkoviittaus,
jonka indeksi on induktiomuuttuja.
Silmukan per{kk{isill{ kierroksilla tapahtuvien vektoriviittausten
et{isyys muistissa (sanoina) on vakio eli invariantti nimelt{{n 
</sl/ii<askel>> (/ii<stride>).
  
 
Jotta silmukka olisi vektoroituva, sen on t{ytett{v{ seuraavat 
minimivaatimukset:
 
/beginitems
 
/item<1)> Silmukassa on sijoituslauseen vasemmalla puolella
          ainakin yksi vektoriviittaus. Poikkeuksena t{h{n
          on ns. reduktio, josta tarkemmin v{h{n my|hemmin.
/item<2)> Kaikki silmukassa esiintyv{t yksinkertaiset muuttujat
          ovat invariantteja, tilap{isi{ skalaareja tai
          induktiomuuttujia.
/item<3)> Sijoituslauseen vasemmalla puolella esiintyy vain
          vektoriviittauksia, tilap{isi{ skalaareja tai
          induktiomuuttujia.
 
/enditems
 
Mik{li n{it{ ehtoja ei ole t{ytetty, ei silmukalla ole
potentiaalisia mahdollisuuksia vektoroituvuuteen.
Mutta n{m{ ehdot eiv{t viel{ takaa, ett{ silmukka
voidaan suorittaa vektoroituna. Silmukassa voi esiinty{
rakenteita, joiden takia vektorikoodi antaisi eri
tuloksia kuin skalaarikoodi tai joita k{{nt{j{ ei osaa vektoroida.
T{llaisia vektoroinnin est{vi{ rakenteita ovat mm.
 
/beginitems
 
/item<$/bullet$> Muuttujien v{liset </sl/ii<riippuvuudet>>, jotka
         vaativat, ett{ silmukan kukin kierros on suoritettava 
         valmiiksi ennen seuraavan aloittamista.

/item<$/bullet$> I//O-lauseet.

/item<$/bullet$> Aliohjelma- ja funktiokutsut (ei koske sellaisia 
         </sc fortran>in intrinsic-funktioita, joista on olemassa
         vektoriversiot). Assemblerilla on tosin mahdollista kirjoittaa 
         aliohjelmia, jotka eiv{t est{ vektorointia.
         </sc fortran>illa t{m{ ei onnistu. /iii<vektorifunktio>

/item<$/bullet$> </tt return> ja </tt stop>.

/item<$/bullet$> Aritmeettiset </tt if>-lauseet, nuo muinaisj{{nteet
         </sc fortran>in ensimm{isten versioiden ajoilta.

/item<$/bullet$> </tt goto> -lauseet taaksep{in.

/item<$/bullet$> </tt goto> -lauseet silmukan ulkopuolelta silmukan 
         p{{tt{v{{n osoitteeseen.
 
/enditems
 
Tarkastellaan viel{ alussa ollutta esimerkki{
 
</copymode
      do 1 i=1,n
         c(i)=a(i)*b(i)
 1    continue
>
 
Tavallinen skalaarikone hakee ensin muistista alkiot </tt a(1)> ja
</tt b(1)>, kertoo ne kesken{{n, tallettaa </tt c(1)>:een ja toistaa
sitten saman kaikille muille alkioille. Vektoriprosessori sen sijaan
lataa ensin vektorirekistereihin koko </tt a>:n ja </tt b>:n, laskee
niiden tulon liukuhihnamenetelm{ll{ mahdollisesti 
kolmanteen vektorirekisteriin, ja
tallettaa lopuksi tuloksen muistiin. Muuttujien haku muistista ja
talletus muistiin voivat tapahtua osittain samanaikaisesti
laskennan kanssa eli muistiviittaukset ja laskutoimitus on
ketjutettu.
 
Edellisess{ esimerkiss{ </tt c(1)> ei siis ole viel{ valmiina
ruvettaessa laskemaan </tt c(2)>:ta.  Jos </tt c(2)>:n laskemiseen
tarvittaisiin </tt c(1)>:n arvoa, liukuhihnoitettu vektorikertolasku
antaisi v{{r{n tuloksen.  Seuraava silmukka on esimerkki tapauksesta,
jossa vektorioperaatiota ei saa k{ytt{{:
 
</copymode
      do 1 i=2,n
         x(i)=x(i-1)+...
  1   continue
>
 
T{ss{ </tt x(i)>:n laskemiseen tarvitaan alkiota </tt x(i-1)>,
jonka laskeminen on viel{ kesken. Silmukassa esiintyy
sijoituslauseiden v{linen /ii<riippuvuus>, jonka vuoksi silmukan
suorittaminen vektoroituna antaa v{{ri{ tuloksia.
Vektoroivat k{{nt{j{t huomaavat n{m{ riippuvuudet, 
eiv{tk{ suostu tuottamaan vektorikoodia, mik{li se
vaikuttaisi tuloksiin.
 
 
/section<Riippuvuuden tyypit>
 
Kahden lauseen </tt S1> ja </tt S2> v{lill{ vallitsee 
</sl/ii<datariippuvuus>> (/ii<data dependence>), jos
</tt S1> asettaa jonkin muuttujan </tt x> arvon ja
</tt S2> muuttaa tai k{ytt{{ tuota arvoa. Datariippuvuus
voidaan edelleen jakaa kolmeen luokkaan:
 
</bf 1) /ii<Todellinen riippuvuus>> (/ii<true dependence>, 
/ii<flow dependence>).
Lause </tt S1> on suoritettava ennen </tt S2>:ta, jotta
</tt S2>:n tarvitsema </tt x>:n arvo olisi laskettu, kun
siihen viitataan:
 
</copymode
       S1:    x  = ...
       S2:   ... = x
>
 
</bf 2) /ii<Antiriippuvuus>> (/ii<antidependence>). Lause </tt S1>
on suoritettava ennen </tt S2>:a, jotta </tt S1> saa
k{ytt||ns{ oikean, muuttamattoman </tt x>:n arvon:
 
</copymode
       S1:   ...  = x
       S2:     x  = ...
>
 
</bf 3) /ii<Tulosriippuvuus>> (/ii<output dependence>). Lauseet
</tt S1> ja </tt S2> muuttavat molemmat </tt x>:n arvoa.
Jotta </tt x>:{{n j{isi oikea arvo, on </tt S2>
suoritettava vasta </tt S1>:n j{lkeen.
 
</copymode
       S1:    x  = ...
       S2:    x  = ...
>
 
Edell{ olleen esimerkin silmukka
 
</copymode
      do 1 i=2,n
         x(i)=x(i-1)+...
  1   continue
>
 
toimii ik{{nkuin suoritettaisiin per{kk{in lauseet
 
</copymode
      x(2)=x(1)+...
      x(3)=x(2)+...
      ...
      x(n)=x(n-1)+...
>
 
N{emme, ett{ t{ss{ on todellinen riippuvuus: kunkin sijoituslauseen
oikealla puolella esiintyy muuttuja, jonka arvo on laskettu
edellisess{ lauseessa. Kyseess{ on ns. </sl/ii<rekursio>> 
(/ii<recurrence>).
 
My|s /ii<skalaari>muuttujat voivat aiheuttaa riippuvuuksia. 
Mik{li silmukassa muutetaan skalaarimuuttujaa siten, ett{
uusi arvo riippuu vanhasta, on seurauksena rekursio.
/ii<Reduktio>silmukka (ks. /ref<13.4>) on esimerkki silmukasta, jossa
skalaaria p{ivitet{{n joka kierroksella. Se voidaan
kuitenkin vektoroida n{enn{isest{ riippuvuudesta huolimatta,
kun huomataan, ettei skalaarin arvoa itse asiassa
tarvita mihink{{n ennen silmukan p{{ttymist{.
 
/section</ii<Riippuvuuksien havaitseminen>>
 
Oleellista on tunnistaa sellaiset silmukat, joissa on
vektoroinnin est{vi{ riippuvuuksia, koska niiden
suorittaminen vektoroituina voisi antaa virheellisi{
tuloksia. Kaikki (?) vektoroivat k{{nt{j{t kyll{
selviytyv{t t{st{. Sen sijaan k{{nt{jien kyky l|yt{{
vektoroituvia silmukoita vaihtelee aika tavalla.
K{{nt{j{t ovat t{ss{ suhteessa varovaisia:
jos silmukassa on jotain ep{ilytt{v{{, jonka
vaikutusta k{{nt{j{ ei osaa p{{tell{,
se ei vektoroi silmukkaa.
 
Seuraava menetelm{ riippuvuuksien l|yt{miseksi on
yksinkertainen, mutta hieman karkea; se ei l|yd{ 
kaikkia vektoroituvia silmukoita. Se on kuitenkin
k{tev{ apuv{line ohjelmoijalle, joka haluaa nopeasti
saada k{sityksen ohjelman vektoroituvuudesta.
 
Etsit{{n silmukasta lause, jossa taulukon alkio
esiintyy sijoituslauseen vasemmalla puolella. T{m{ 
</sl/ii<p{{viittaus>> jakaa silmukan kahteen osaan, edelt{v{{n
eli yl{puoliseen ja seuraavaan eli alapuoliseen:
 
/null/vskip5truecm
 
Katsotaan, viitataanko samaan taulukkoon muualla.
Ellei viittauksia ole, ei taulukko aiheuta my|sk{{n
riippuvuusongelmia. Mik{li toinen viittaus l|ytyy, 
tutkimme kolme asiaa, joista jokaisen
tuloksena saamme luvun +1 tai -1.
 
/beginitems
/item<1)> Jos toinen viittaus esiintyy ennen
          p{{viittausta eli sen yl{puolella ohjelmalistassa,
          panemme mieleen luvun +1, jos taas sen alapuolelle, luvun -1.
/item<2)> Jos toisessa viittauksessa indeksi on suurempi tai 
          yht{suuri kuin p{{viittauksessa, saamme toiseksi 
          luvuksi +1, muuten -1.
/item<3)> Jos silmukan askel on positiivinen, kolmas lukumme on +1 ja
          -1, jos askel on negatiivinen.
 
/enditems
 
Nyt sitten vain kerromme saamamme kolme lukua kesken{{n.
Jos tulo on +1, voi silmukan vektoroida turvallisin mielin.
Jos se on -1, silmukassa saattaa esiinty{ haitallinen
riippuvuus.
 
Esimerkkin{ tarkastelemme silmukkaa
 
</copymode
      do 1 i=2,n-1
         a(i)  =a(i)+b(i+1)-c(i)
         b(i-1)=a(i-1)+c(i)
         d(i-1)=c(i+1)
   1  continue
>
 
Pelk{st{{n selk{ytimell{ ajatellen t{ss{ mahdollisesti 
vaanivat riippuvuudet eiv{t ole aivan ilmeisi{. 
Kokeillaan siis, mit{ voimme p{{tell{ silmukasta
alkeellisen algoritmimme avulla.
 
Aluksi havaitsemme, ett{ </tt c> esiintyy vain sijoituslauseen
oikealla puolella ja </tt d> vain vasemmalla puolella, joten
niist{ ei tarvitse murehtia. Sen sijaan sek{ </tt a> ett{ </tt b>
esiintyv{t sijoituslauseen molemmilla puolilla, joten kumpikin
saattaa aiheuttaa riippuvuuden. 
 
Tarkastellaan ensin </tt a>:ta. Sen p{{viittaus on </tt a(i)=...>.
Sen yl{puolisesta osasta (t{ss{ tapauksessa 
saman sijoituslauseen oikealta puolelta) l|ytyy viittaus </tt a(i)>,
ja ensimm{inen luku on siis +1.
T{m{n indeksi on sama kuin p{{viittauksessa, joten toinen luku on 
my|s +1. Silmukkaindeksi </tt i> on kasvava, joten kolmaskin luku
on +1. N{iden kolmen luvun tulo on +1; siisp{ t{m{ viittauspari ei
aiheuta riippuvuutta. 
 
Toinen viittaus </tt a>:han on p{{viittauksen alapuolella
(-1), ja siin{ indeksi on pienempi (-1) kuin
p{{viittauksessa.  Silmukkaindeksi on edelleen kasvava (+1),
joten taaskin tulo on +1, eik{ t{m{k{{n viittaus aiheuta
riippuvuutta. 
 
J{ljell{ on viel{ </tt b>. P{{viittaus on </tt b(i-1)=...>.
Toinen viittaus </tt b(i+1)> on sen yl{puolella (+1) ja
siin{ indeksi on p{{viittausta suurempi (+1). Koska silmukkaindeksi
on yh{ edelleen kasvava (+1), on tulo taaskin +1.
 
Tutkittuamme kaikki kolme viittausparia huomaamme kaikkien
antavan tulokseksi +1, joten silmukka on vektoroituva
hieman sotkuisen n{k|isist{ taulukkoviittauksista huolimatta.
 
T{ll{ menetelm{ll{ j{{v{t l|ytym{tt{ jotkut sellaiset vektoroituvat
silmukat, joissa askel ei ole +1 tai -1. Seuraava Crayn k{{nt{j{n
k{ytt{m{ menetelm{ havaitsee my|s n{m{.
 
Tarkastellaan taaskin kahta viittausta, jotka esiintyv{t
sijoituslauseen eri puolilla. Olkoon edellisess{ taulukon
indeksi </tt I1> ja j{lkimm{isess{ </tt I2>. Kirjoitetaan
n{m{ muotoon
 
</copymode
      I1 = $a_1 + b * i$
      I2 = $a_2 + b * i$
>
 
miss{ $a_1$, $a_2$ ja $b$ ovat vakioita ja $i$
on silmukan kierroslaskuri (siis ei </tt do> -lauseessa
esiintyv{ silmukkaindeksi).
 
Viittausten v{lill{ vallitsee riippuvuus, jos molemmat seuraavista
ehdoista ovat voimassa:
 
</copymode
      $</rm sign>(a_2-a_1) = </rm sign>(b)$
      $/vert a_2-a_1 /vert </rm mod> b = 0$
>
 
Sovelletaan t{t{ seuraavaan silmukkaan:
 
</copymode
      do 1 k=1,n-1,2
         a(k+1)=a(k)+b(k)
   1  continue
>
 
Aikaisempi menetelm{mme sanoisi, ett{ t{ss{h{n on
riippuvuus </tt a>:n suhteen. Mutta tutkitaanpa asiaa
tarkemmin. Ensimm{inen viittaus on nyt </tt a(k)>
(sijoituslauseen oikea puolihan kuului edelt{v{{n osaan)
ja toinen </tt a(k+1)>. Kirjoitetaan indeksit muotoon
 
</copymode
      I1 = k     = 0 + 2 * $i$
      I2 = 1 + k = 1 + 2 * $i$
>
 
joten vakiomme ovat $a_1=0$, $a_2=1$ ja $b=2$. 
Tutkitaan sitten riippuvuusehtoja 
 
</copymode
      $</rm sign>(1-0) = +1 = </rm sign>(2)$
      $/vert 1-0 /vert </rm mod> 2 = 1 /ne 0$
>
 
Huomaamme, ett{ j{lkimm{inen ehto ei ole voimassa ja
silmukka voidaan siis vektoroida. 
Syy t{h{n n{kyy selv{sti, jos silmukan kirjoittaa auki.
Sijoituslauseen vasemmalla puolella esiintyy vain
parillisia indeksej{ ja oikealla vain parittomia,
joten vasen ja oikea puoli ovat toisistaan t{ysin
riippumattomia.
 
/section<Erikoistapauksia>
 
On olemassa muutamia usein esiintyvi{
silmukkatyyppej{, jotka vektoroituvat, vaikka 
n{enn{isesti sis{lt{v{tkin riippuvuuksia.
 
</copymode
      s=0.0
      do 1 i=1,n
         s=s+x(i)
   1  continue
>
 
T{ss{ on kysymyksess{ </sl/ii<reduktio>>, jossa vektori
redusoidaan skalaariksi. T{llainen operaatio on niin
yleinen, ett{ n{enn{isest{ rekursiosta huolimatta
k{{nt{j{t osaavat vektoroida sen. T{m{ onnistuu
l{hinn{ siksi, ettei </tt s>:n arvoa itse asiassa
tarvitse p{ivitt{{ ennen kuin koko summa on laskettu.

Vektoroituvissa silmukoissa kierrosm{{r{ on yleens{
selvill{ ennen silmukan suoritusta. Jos silmukka
p{{ttyy silmukan sis{ll{ laskettavan ehdon toteutuessa
(kuten muiden kielten </tt/ii<while>>-rakenteissa),
se ei todenn{k|isesti vektoroidu, paitsi jos lopetusehto
on riitt{v{n yksinkertainen.
T{st{ esimerkkin{ on ns. /ii<hakusilmukka> (/ii<search loop>),
josta hyp{t{{n ulos sopivan ehdon toteutuessa:

</copymode
      do 1 i=1,n
         ...
         if (x(i).gt.0.0) goto 100
   1  continue
 100  ...
>

T{llainen silmukka vektoroituu, mutta lopetusehto ei saa
olla yht{{n monimutkaisempi.
 
Seuraavassa silmukassa on rekursio </tt a>:n suhteen:
 
</copymode
      do 1 i=11,n
          a(i)=a(i-10)+1.0
    1 continue
>
 
Vaikka </tt a(i-10)> onkin laskettu kymmenen kierrosta
aikaisemmin, ei kuitenkaan voi turvallisesti olettaa,
ett{ sen uusi arvo olisi k{ytett{viss{. Sen sijaan
voimme paloitella silmukan kymmenen kierroksen
mittaisiin p{tkiin. T{llaisen palasen sis{ll{ ei
en{{ esiinny riippuvuutta, koska jokainen </tt a(i-10)>
on laskettu jo edellist{ palasta k{sitelt{ess{.
Silmukka siis vektoroituu, mutta vektorin pituus on 
nyt vain 10.
 
Joissakin tapauksissa riippuvuuden luonnetta ei voi 
p{{tell{ k{{nn|saikana, jolloin k{{nt{j{ k{sittelee
silmukan samalla tavoin kuin edellisess{ esimerkiss{,
mutta vektorin pituus on nyt muuttuja. 
Vektorin pituus selvi{{ suoritusaikana. Pahimmassa
tapauksessa silmukassa on riippuvuus, joka vaatii
k{ytt{m{{n vektorin pituutta yksi, jolloin 
ohjelma toimii ik{{nkuin skalaarikoodi.
T{m{ on niit{ harvoja tapauksia, joissa 
vektorikoodi toimii skalaarikoodia hitaammin.
Ainoa keino est{{ t{llaisen hidastavan vektorikoodin
tuottaminen on direktiivien k{ytt| (ks. /ref<16.2>).
 
Seuraava esimerkki esitt{{ tilannetta, jossa
k{{nt{j{ tuottaa t{llaista </sl/ii<ehdollista vektorikoodia>>
(/ii<conditional vectorization>):
 
</copymode
      subroutine f(a,b,n)
      real a(1000),b(1000)
      do 1 i=n+1,1000
         a(i)=a(i-n)+b(i)
   1  continue
      end
>
 
Jos </tt n> on ainakin vektorirekisterin pituuden suuruinen
($n /ge 64$), on silmukka t{ysin vektoroituva. Samoin jos </tt n> on
nolla tai negatiivinen, ei silmukassa ole lainkaan
riippuvuuksia. Vaikeuksia tulee, jos $0 /lt </tt n> /lt 64$.
T{ll|in silmukka vektoroituu vain </tt n>:n mittaisina
palasina. Erityisesti jos $</tt n>=1$, on kukin
vektoroituva palanen yhden alkion mittainen, ja
seurauksena on skalaarikoodia hitaammin toimiva
ohjelma. 
 
Crayll{ jo 2--3 kierroksen mittaiset silmukat kannattaa
suorittaa vektoroituina, joten ehdollisesti vektoroituvat
silmukat kannattaa pakottaa skalaarikoodiksi direktiiveill{
yleens{ vain, jos silmukan pituus on useimmiten yksi.







