【问题标题】:Faster Code Anyone? :) [closed]更快的代码有人吗? :) [关闭]
【发布时间】:2013-05-18 03:10:58
【问题描述】:

编辑:通过以下方式节省了大约 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,

... 继续

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

【问题讨论】:

  • “我在此宣布 Nik Bougalis 在尝试压缩我的代码之前获得 500,000 美元,并在他成功给我留下深刻印象后再获得 500,000 美元。” :)
  • 太模糊了。也不具有法律约束力。
  • 你删了我的帖子吗? Duddeee com 上 broski
  • 最快的方法就是让函数的第一行dtw:return false
  • 一个整数本身相乘实际上比查找函数快得多...

标签: c performance algorithm


【解决方案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))

如果宏版本的参数有副作用,当然不应该使用它,因为它会计算不止一次。

【讨论】:

  • 是的,乘法发生大约 64*64*15 次(61440 次),当我双向计算时,查找速度更快。但我确实喜欢你对内联的建议!谢谢!
  • 嘿乔普!所以我输入了你的宏版本,顺便说一句好主意,我想知道你所说的副作用是什么意思???谢谢!
  • 副作用是如果你调用像 val = lookUp(i++); 这样的宏(或通过具有副作用的函数,如 getc())
【解决方案2】:

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

让你的大脑更聪明地做到这一点。

【讨论】:

  • 是的,它看起来很丑,感谢您的贡献!我重试了:
  • 请参见上文进行编辑。 . .
  • 请记住,有些事情很难改变,因为 row 和 col 的大小与输入的单词一起是动态的
  • @user2368363:int temp1 = abs( *libwordPointer - *wordsPointer ); temp += temp1*temp1; 怎么了?
  • 速度较慢。每次进入我都会做 60,000 次。
【解决方案3】:

这些都是技巧——它们可能不会使您的代码更易于维护,但是...

小技巧,可能会给你几个百分点:
与其在 for(...) 循环中计数,不如倒数到 0。许多 CPU 创建更紧凑的代码,测试为 0 而不是 N。另外,如果您 知道第一次通过循环 必须发生,使用 do ... while 循环

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

改成

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

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

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

到 浮动 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”除外),而是始终使用整数数学运算。看来你可以过得去。

干杯!

【讨论】:

  • 好主意,谢谢 Chux!
猜你喜欢
  • 1970-01-01
  • 2017-01-18
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 2011-05-20
  • 1970-01-01
  • 2015-10-28
相关资源
最近更新 更多