2016-07-31 3 views
2

本質的に、私は以下のコードで計算された値を使用しようとしていますが、独自のレートを持つすべてのオブジェクトに値を格納すると、キャッシュミスを引き起こす。また、ルックアップテーブルを使用することは明らかに重要ではありません。浮動指数を持つ2の速い乗数[C]

標準出力関数よりもこれらの値を高速に取得する方法を探していますが、可能な入力が非常に制限されているために使用できるトリックはありますか?

static inline 
double __attribute((pure)) get_decay_rate(uint8_t rate) 
{ 
    if(rate >= 128) 
    { 
      return 65535.0/65536.0; 
    } 

    double k = pow(2, rate/8.0); 
    return (k - 1.0)/k; 
} 


/* pseudocode: 
    double k = (int) pow(2, k/8.0); 
    k = (k - 1)/k; 
    return log(65535/65536)/log(k); 
*/ 
static inline 
uint16_t __attribute((pure)) get_decay_modulus(uint8_t rate) 
{ 
    if(rate <= 128) 
    { 
      return 1; 
    } 
//turns out to be the same as the above pseudocode, for some reason. 
    return pow(2, (rate - 128)/8.0); 
} 
+0

そして、あなたはまた、各関数に静的な256の長さの配列を入れてみましたか?または、静的な128の長さの配列? – Hurkyl

+0

int k = pow(2、k/8.0);で 'rate/8.0'を意味しますか?同様に 'get_decay_modulus'では' k'を宣言せずに 'k'を参照します。 – oldrinb

+0

@Hurkyl問題はキャッシュミスなので、キャッシュに収まるコードが少なくなるので、問題を解決するのではなく移動します。 –

答えて

2

この行を取る:

double k = pow(2, rate/8.0); 

は、基本的にはあなたがここで何をしているか、固定小数点数のパワーに2を上げています。

pow(a、b + c)= pow(a、b)* pow(a、c)、および非整数の数=整数の部分+小数部分を利用できます。したがって、固定小数点数の整数部分でpowを計算し、小数部のpowでそれを掛けます。

ストアルックアップテーブルの8つの小数指数:小数部から

double k = (double)(1 << (rate >> 3)) * fractionalPowersOf2[rate & 7]; 

このマスクとテーブルルックアップのためにそれを使用しています。

double fractionalPowersOf2[8]; 

for(int i = 0; i < 8; i++) 
    fractionalPowersOf2[i] = pow(2.0, i/8.0); 

その後、あなたはこのようなあなたの計算を行うことができますビットシフトを使用して積分部分のべき乗に2を掛けた値を乗算します。倍精度化のキャストが遅すぎる場合は、そのためにルックアップテーブルを使用することもできます。

キャストポインタなどで2倍の指数として値を使用するという、魅力的なbitmagic型のアプローチを使用することもできますが、これは移植できません。

編集:コメントでuser3386109で指摘したように、あなたが最適化をオンにした場合、コンパイラはあなたのための整数値のパワーに2を上げる最適化することができるので、このコードがより速くなることがあります。

double k = pow(2,rate>>3) * table[rate&7]; 
+0

ありがとう、それは完璧です! –

+1

@samgak最適化を有効にした状態で 'double k = pow(2、rate >> 3)* table [rate &7];'を指定すると、コンパイラはあなたのために指数部のファンシービットマジックを行います。 – user3386109

+1

@ user3386109:私はセマンティクス*が本当に魅力的なビットマジックを許しているのか心配しています。そして、整数計算では魔法を実行しないと懐疑的です。いずれにしても、浮動小数点関数の呼び出しを主張する場合は、おそらく 'ldexp'がここで使用する方が良いでしょう。 (プロファイリングが必要!) – Hurkyl

関連する問題