2016-12-11 4 views
0

これは、バイト文字列上で動作SDBMハッシュアルゴリズムのためのコードです...SDBMハッシュ同時に

unsigned long sdbm(unsigned char *key, int bytes) 
{ 
    unsigned long hash = 0; 
    unsigned char *end = key + bytes; 
    while (key < end) hash = (unsigned long)(*key++) + (hash << 6) + (hash << 16) - hash; 
    return hash; 
} 

はSDBMに渡された文字列のすべてが()4つのバイトだったことになりましたと。代わりに32ビットの符号なしの値として文字列を扱う、すべての4バイトのsdbmハッシュを一度に計算する方法はありますか?私は、文字列のキーが、これは、両方の関数が同じ値を計算し、sdbm4()が4バイトの文字列を処理するために特化されていることを明らかにします実行中のすべての4バイト

#define SUBHASH(x) ((x << 6) + (x << 16) - x) 
unsigned long sdbm4(unsigned long key) 
{ 
    unsigned long hash = (key & 0xFF); 
    hash = ((key & 0xFF00) >> 8) + SUBHASH(hash); 
    hash = ((key & 0xFF0000) >> 16) + SUBHASH(hash); 
    return (key >> 24) + SUBHASH(hash); 
} 

char *tmp = "test"; 

int main(void) 
{ 
    unsigned long a = sdbm((unsigned char *)tmp, 4); 
    unsigned long b = sdbm4(*(unsigned long *)tmp); 

    printf("a = %lu, b = %lu\n", a, b); 

    while (!_kbhit()); 
    return 0; 
} 

であると仮定すると、このコードを持っています。ループが発生せず、テストも行われず、スタック上の値はすぐに最初の値に初期化されます。しかし、これを4つではなく1つのステートメントに凝縮する方法があればうまくいくでしょう。それは可能ですか?私はSIMDがおそらくそれを行うことができると考えましたが、どのように、あるいは何らかの利益があるかどうかはわかりません。

答えて

0

明らかにが完了したのはなので、ステートメントをインラインで4回展開するだけです。 SUBHASHの定義は式を渡すと中断されますので、修正する必要があります。そのため、インライン関数にすることもできます。

inline constexpr unsigned long SubHash(unsigned long x) { 
    return ((x << 6) + (x << 16) - x); 
} 


inline constexpr unsigned long sdbm4(unsigned long key) 
{ 
    return (key >> 24) + 
       SubHash(((key & 0xFF0000) >> 16) + 
        SubHash(((key & 0xFF00) >> 8) + 
         SubHash(key & 0xFF)))); 
} 

私はそれが価値があった場合、私は非常に驚くだろう。このルールは、プロファイリングが最適化を開始する際に問題があることが示されている場合にのみ、まず明確にするためのコードを記述することです。 (ほとんど常に間違っているボトルネックがある可能性が高い場所へと1つの本能に注意してください。)あなたが本当にがに#defineを使用したい場合は

、あなたはそれを変更する必要があります。

#define SUBHASH(x) (((x) << 6) + ((x) << 16) - (x)) 

あなたは、生成されたコードが同一であることは間違いないかもしれません。

+0

ローカルWebサーバーの負荷を軽減するために、できるだけ少ないステートメントをCGI実行可能ファイルから絞り込もうとしています。 CPUは、最新のCPUほど効率的ではない古いIntelプラットフォーム間で異なる場合があります。あなたのコードは私のものより少し改善されていると思います。私はそのノートに感謝します。しかし、私はまだ1つのステートメントに4つのオペレーションが広がっているのではなく、32ビット長の1つのオペレーション*でハッシュ全体を解決することに興味があります。これは可能ではないかもしれませんが、私はそれに一撃を与えると思いました。 – Lemming

+0

1.この機能がボトルネックになっていると私は驚いています(しかし、私はほとんどのプログラマのように、ボトルネックを予測するのが面倒です)。 2.「ワン・オペレーション」とはどういう意味ですか? 1つの命令? - 起こらないだろう。そうでない場合は、実際に気になるのはCPUサイクルの数だけです。実際に測定することを知る唯一の方法です。 –

+0

まあ、私は "感謝"(それはルールに反する)と言うべきではないと知っている...しかし、ガイダンスのために感謝:) – Lemming

関連する問題