更快的代码? :)

时间:2013-05-22 22:06:54

标签: c performance algorithm

编辑:使用以下方法削减大约10%的处理时间:

register int16_t *libwordPointer = libword;
int16_t *nReset;
register int16_t *wordsPointer = words[word];
int16_t *mReset = wordsPointer;

for( int n=0 ; n<Rows ; n++ ){  
    nReset = libwordPointer;
    wordsPointer = mReset;
    for( int m=0 ; m<Col ; m++ ){
        temp = 0;
        libwordPointer = nReset;
        for( int ii=0 ; ii<Q ; ii++ ){
            temp += lookUp( abs( *libwordPointer - *wordsPointer ) );
            libwordPointer++;
            wordsPointer++;
        }
        D[n][m] = temp;
    }
}

/////////////////////////////////////////////// ////////////////////////////////////////////

关于如何让这更快的任何专家意见????奖励是一百万美元:)

 float dtw( int16_t (*words)[L][Q], int16_t (*libword)[Q], int16_t libcount, char word ){


    float Dist, k=0;
//  int Dn;
    register int Rows = libcount;   
    register float A, B, C; 
    register float temp;    
    register int Col = ender[word]-begin[word]+1;   // rows for word being tested

    for( int n=0 ; n<Rows ; n++ ){      
        for( int m=0 ; m<Col ; m++ ){
            temp = 0;
            for( int ii=0 ; ii<Q ; ii++ ){
                temp += lookUp(abs(libword[n][ii]-words[word][m][ii]));
            }
            D[n][m] = temp; 
        }
    }

    for( int n=1 ; n<Rows ; n++ ){                      
        D[n][0] += D[n-1][0];
    }
    for( int m=1 ; m<Col ; m++ ){
        D[0][m] += D[0][m-1];
    }
    for( int n=1 ; n<Rows ; n++ ){
        for( int m=1 ; m<Col ; m++ ){
            D[n][m] += mininum1( D[n-1][m], D[n-1][m-1], D[n][m-1] );
        }
    }

    Dist=D[Rows-1][Col-1];                          // minimum distance to end
    register int n=Rows-1;                          // now work backwards
    register int m=Col-1;
    k=1;
    while( (n+m) != 0 ){
        if( n == 0 ){
            m--;
        }else if( m == 0 ){
            n--;
        }else{
            A=D[n-1][m];
            B=D[n][m-1];
            C=D[n-1][m-1];
            if( A < B ){
                if( A < C ){
                    n--;
                }else{
                    n--;
                    m--;
                }
            }else if( B < C ){
                m--;
            }else{
                n--;
                m--;
            }

        }
        k++;
    }

    return Dist/k;
}

其中查找是这样的:

float lookUp(int16_t pow){

    if( pow < MAX_DIFFERENCE ){
        return powLookup[pow];

    }else{
        return MAX_DIFFERENCE_POW;
    }

}

和powLookup是这样的:

const float powLookup[MAX_DIFFERENCE]={
    0,
    1,
    4,
    9,
    16,
    25,
    36,
    49,
    64,
    81,
    100,
    121,
    144,
    169,
    196,
    225,
    256,

......和

这个想法是在微指令方面提高效率。您可以看到我尝试通过电源查找使其更好,但它仍然是处理中的杀手。欢迎任何想法。也许更快的方式索引数组?

3 个答案:

答案 0 :(得分:1)

内部循环中只有(n * n)的查找表会受到伤害(在大多数体系结构中乘法并不昂贵。函数调用是)。您至少可以通过内联函数或宏来替换它:

static inline float lookUp(int16_t num)
{
return (num >= MAX_DIFFERENCE) ? MAX_DIFFERENCE_POW : num*num;
}

宏版本:

#define lookUp(n) (((n) >=MAX_DIFFERENCE) ? MAX_DIFFERENCE_POW : (n)*(n))

如果在其参数中存在副作用,则当然不应使用宏版本,因为它会多次计算。

答案 1 :(得分:0)

你有一个三重嵌套的循环,在最里面的循环中,你正在做一个三重索引,并使用一个带有表查找的函数调用来对一个数字进行平方。

吸引你的大脑,更聪明地做到这一点。

答案 2 :(得分:0)

这些技巧 - 可能无法使您的代码更易于维护,但是......

小技巧,可能会给你几个百分点:
而不是计数(...)循环,倒计时为0.许多CPU使用0而不是N来创建更严格的代码。此外,如果你知道第一次通过循环< em>必须发生,使用do ... while循环

for( int ii=0 ; ii<Q ; ii++ ){

更改为

int ii=Q;
do {
  ...
} while (ii-- > 0);

第二招(只有一点帮助) 该循环重新查找“D [n] [m-1]”。当你在列表中运行时,下一个循环“D [n] [m-1]”的D [n] [m]相同;

for( int m=1 ; m<Col ; m++ ){
  D[n][m] += mininum1( D[n-1][m], D[n-1][m-1], D[n][m-1] );

要     float Dprevious = D [n] [1] + = mininum1(D [n-1] [1],D [n-1] [1-1],D [n] [1-1]);     for(int m = 2; m

您可以在“while((n + m)!= 0){”循环中执行此操作。

第三个想法:大招:我假设你的浮点必须是昂贵的,否则,为什么lookUp()?因此,不是做任何浮点数学(除了可能最后的“Dist / k”),而是使用整数数学。看起来你可以顺其自然。

干杯!