编辑:使用以下方法削减大约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,
......和
这个想法是在微指令方面提高效率。您可以看到我尝试通过电源查找使其更好,但它仍然是处理中的杀手。欢迎任何想法。也许更快的方式索引数组?
答案 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”),而是使用整数数学。看起来你可以顺其自然。
干杯!