バックグラウンド
私は、OpenGL レンダリング パイプラインの段階で必要な小さな静的ハッシュ テーブル (線形プローブ) を使用します。そこでは、int64_t 型のキーといくつかのデータをできるだけ速く取得して更新する必要があります。要するに、この段階では、大きな ID を、後続の段階で使用する小さなローカル インデックスに変換します (したがって、この段階では、64 ビット キーを 1 回処理する必要があり、32 ビット キーは使用できません)。
私は、32 ビットと 64 ビットの両方のアーム アーキテクチャ (iOS と Android スマートフォン) で高速に動作するハッシュ関数を見つけるために、長い間実験してきました。当然のことながら、32 ビット デバイスでは、64 ビット キーのハッシュは 32 ビット キーのハッシュよりもはるかに遅くなります (私のテスト ケースではほぼ 10 倍)。
SOでここで見つけたハッシュに非常に自信を持っています。これは、私の場合、MurmurHash3 32ビットファイナライザーよりも優れています(さらに衝突がありますが、私の場合は問題ではありません): https://stackoverflow.com/a /12996028/1708349
今のところすべて正常に動作しますが、ここに問題があります。ハッシュ化する前に、64 ビット キーを単純に int32_t 型に割り当てます。これは、32 ビット プラットフォームのパフォーマンス上の理由から行われます。これは機能しているようで、大きなデータがラップされています。しかし、問題はもちろん、この動作が定義されていないことです。
だから、私の質問は次のとおりです: int64_t 型を int32_t 型に割り当てるのに最適なもの (定義されたコンパイラの動作など) は何ですか?
これは私の実際のハッシュ関数です:
inline int32_t hash2(int64_t k) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
int32_t x = k;
#pragma clang diagnostic pop
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x);
return x;
}