[LUGOS-PROG] Loop speedup

Ivo List ivo.list at guest.arnes.si
Wed Jul 28 21:50:44 CEST 2004


Probi tole z g++ -O3:
double ed(Feature *_f1, Feature *_f2) {
        int fSize = _f1->getSize();
        int *f1Value = _f1->getValue();
        int *f2Value = _f2->getValue();

        register long dist = 0;
        int i = fSize-1;
        while (i>=0) {
                int d = (f1Value[i]) - (f2Value[i]);
                dist += d * d;  

                i--;
        } // for

        return sqrt(dist);
} // euclideanDistance

Asm za zanko je:
0x080484c0 <ed+32>:     mov    (%esi,%edx,4),%eax
0x080484c3 <ed+35>:     sub    (%ebx,%edx,4),%eax
0x080484c6 <ed+38>:     imul   %eax,%eax
0x080484c9 <ed+41>:     add    %eax,%ecx
0x080484cb <ed+43>:     inc    %edx
0x080484cc <ed+44>:     jne    0x80484c0 <ed+32>

Ena optimizacija, ki ti ostane, je se loop unrolling. Sm jo probal samo zmede 
compiler in zaradi nje popacka se en register. Kako bi koda zgledala si 
poglej spodaj (ja, je standardni C++):

MMX procesorji imajo drugace tudi ukaze za to:
http://homepages.cae.wisc.edu/~ece734/mmx/AP-564.html
Fora je, da ima MMX matricne registre, kjer naenkrat nafilas not 8 cifer, 
potem dva taka registra odstejes in skvadriras vse cifre, ki jih vsebujeta.

double ed(Feature *_f1, Feature *_f2) {
        int fSize = _f1->getSize();
        int *f1Value = _f1->getValue();
        int *f2Value = _f2->getValue();

        long dist = 0;
        int i = fSize-1;
        switch (i%8) {
                while (i>=0) {
                   int d;
                   case 7:
                        d = (f1Value[i]) - (f2Value[i]);
                        dist += d * d;
                        i--;
                   case 6:
                        d = (f1Value[i]) - (f2Value[i]);
                        dist += d * d;
                        i--;
                   case 5:
                        d = (f1Value[i]) - (f2Value[i]);
                        dist += d * d;
                        i--;
                   case 4:
                        d = (f1Value[i]) - (f2Value[i]);
                        dist += d * d;
                        i--;
                   case 3:
                        d = (f1Value[i]) - (f2Value[i]);
                        dist += d * d;
                        i--;
                   case 2:
                        d = (f1Value[i]) - (f2Value[i]);
                        dist += d * d;
                        i--;
                   case 1:
                        d = (f1Value[i]) - (f2Value[i]);
                        dist += d * d;
                        i--;
                   case 0:
                        d = (f1Value[i]) - (f2Value[i]);
                        dist += d * d;
                        i--;
                }
        } // for

        return sqrt(dist);
} // euclideanDistance





On Wednesday 28 of July 2004 20:44, Jure Koren wrote:
> On Wed, 28 Jul 2004 19:23:25 +0200, Gregor Berginc
>
> <gregor.berginc at guest.arnes.si> wrote:
> > Na zalost govorim o 128 razseznem prostoru :) Gre namrec za obdelavo
> > slikvonih znacilk, ki jih pridobim z nekim drugim programom.
> >
> > Mislim, da lookup tukaj nikakor ne pride v postev.
>
> Ocitno ne, lahko pa poskusis svoj program prevesti z razlicnimi
> stopnjami optimizacij in gledas, kaj pade ven v assemblerju. Precej
> verjetno je, da bo ena od optimizacij prava (in bo dist padel v nek
> register), saj bi moral optimizer ugotoviti da ves cas hodi po dist
> ven iz procesorja v zelo ozkem loopu. Ce tega ne ugotovi, potem pa
> pojma nimam, kako bi to resil drugace, kot da sam loop napises v
> inline assemblerju.

-- 
I've always made it a solemn practice to never drink anything stronger
than tequila before breakfast.
		-- R. Nesson



More information about the lugos-prog mailing list