これは、バイト文字列上で動作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がおそらくそれを行うことができると考えましたが、どのように、あるいは何らかの利益があるかどうかはわかりません。
ローカルWebサーバーの負荷を軽減するために、できるだけ少ないステートメントをCGI実行可能ファイルから絞り込もうとしています。 CPUは、最新のCPUほど効率的ではない古いIntelプラットフォーム間で異なる場合があります。あなたのコードは私のものより少し改善されていると思います。私はそのノートに感謝します。しかし、私はまだ1つのステートメントに4つのオペレーションが広がっているのではなく、32ビット長の1つのオペレーション*でハッシュ全体を解決することに興味があります。これは可能ではないかもしれませんが、私はそれに一撃を与えると思いました。 – Lemming
1.この機能がボトルネックになっていると私は驚いています(しかし、私はほとんどのプログラマのように、ボトルネックを予測するのが面倒です)。 2.「ワン・オペレーション」とはどういう意味ですか? 1つの命令? - 起こらないだろう。そうでない場合は、実際に気になるのはCPUサイクルの数だけです。実際に測定することを知る唯一の方法です。 –
まあ、私は "感謝"(それはルールに反する)と言うべきではないと知っている...しかし、ガイダンスのために感謝:) – Lemming