对 32 位整数进行哈希处理比对 3 个 16 位整数的哈希进行按位运算慢?
hashing a 32bit integer is slower than bitwise operation on hash of 3 16bit integers?
我正在研究对延迟敏感的软件。今天,我决定通过在联合中使用 BitField 结构来减小结构的大小,并将该 BitField 结构读取为我用作哈希函数的唯一键的整数。我原本期望从唯一键上的哈希中获得比对类的属性哈希的按位运算稍微(如果不是很多(更好的性能,但事实证明,按位运算来获取哈希键要快得多?我一直试图找出原因,但我无法得出任何结论。
这是我的代码:http://quick-bench.com/OkNuVOxdVtW8g7OWUXjqcvYlNrs
#include <functional>
struct GroupTupleInformation {
unsigned int src : 12;
unsigned int dst : 12;
unsigned int flow_id : 8;
};
union GroupTupleData {
GroupTupleInformation info;
uint32_t hash_key;
};
struct GroupTuple {
constexpr void setSrc(uint16_t s) noexcept { data.info.src = s; }
constexpr uint16_t getSrc() const noexcept { return data.info.src; }
constexpr void setDst(uint16_t d) noexcept { data.info.dst = d; }
constexpr uint16_t getDst() const noexcept { return data.info.dst; }
constexpr void setFlowId(uint8_t f) noexcept { data.info.flow_id = f; }
constexpr uint8_t getFlowId() const noexcept { return data.info.flow_id; }
constexpr uint32_t getHashKey() const noexcept { return data.hash_key; }
private:
GroupTupleData data;
};
struct UnionHashFn {
constexpr std::size_t operator()(const GroupTuple& gtup) const noexcept {
return gtup.getHashKey();
}
};
struct CombinedHashFn {
std::size_t operator()(const GroupTuple& gtup) const noexcept {
std::hash<uint16_t> hasher{};
return hasher(gtup.getSrc()) ^ hasher(gtup.getDst()) ^
hasher(gtup.getFlowId());
}
};
static void UnionHashFnBench(benchmark::State& state) {
unsigned long i = 0;
UnionHashFn hasher;
GroupTuple group_tuple;
size_t key = 0;
for (auto _ : state) {
group_tuple.setSrc(i++ % 32);
group_tuple.setDst(i++ % 32);
group_tuple.setFlowId(i++ % 32);
key = hasher(group_tuple);
benchmark::DoNotOptimize(key);
}
}
BENCHMARK(UnionHashFnBench);
static void CombinedHashFnBench(benchmark::State& state) {
unsigned long i = 0;
CombinedHashFn hasher;
GroupTuple group_tuple;
size_t key = 0;
for (auto _ : state) {
group_tuple.setSrc(i++ % 32);
group_tuple.setDst(i++ % 32);
group_tuple.setFlowId(i++ % 32);
key = hasher(group_tuple);
benchmark::DoNotOptimize(key);
}
}
BENCHMARK(CombinedHashFnBench);
PS:我知道制作地图或unordered_map比基准化哈希函数的成本更复杂,而且我也知道我为从类中获取哈希所做的按位运算不是获取哈希的好方法,这只是为了有一个简单的例子
>std::hash<uint16_t>
只是身份(老实说,这是值得怀疑的(,所以表达式:
hasher(gtup.getSrc()) ^ hasher(gtup.getDst()) ^ hasher(gtup.getFlowId())
将优化为非常简单的表达式。它的代码只是:
lea -0x2(%rax),%ecx
lea -0x1(%rax),%edx
xor %ecx,%edx
xor %eax,%edx
and $0x1f,%edx
另一方面,计算hash_key
需要付出更多的努力:
mov %edx,%esi
and $0x1f,%esi
mov %ecx,%edi
and $0x1f000,%edi
or %rsi,%rdi
add $0x3,%rdx
mov %eax,%esi
and $0x1f000000,%esi
or %rdi,%rsi
因此,hash_key
方法较慢也就不足为奇了。
相关文章:
- 如何在 c++ 中生成十六进制二进制数据的 sha256 哈希?
- 如果索引不是整数,我们如何在 C++ 中插入哈希表
- 自定义哈希表实现-将字符串映射到整数时出现内存错误
- 对 32 位整数进行哈希处理比对 3 个 16 位整数的哈希进行按位运算慢?
- 如何将单个字符转换为为基本密码哈希器设置整数,C++
- 如何从 3 个有序整数创建哈希
- 一对整数的哈希算法
- 从 2+ 个整数(快速)创建哈希/种子值
- 有效地将 16 位整数哈希为 256 位空间
- 好的哈希函数,2个整数用于一个特殊的密钥
- 这是什么C++语言结构:#(即哈希)整数"path_to_header_or_cpp_file"<integer>?
- C++:检查字符串是否为有效的 MD5 十六进制哈希
- 迁移一个哈希函数,其中包含从 C++/Qt 到 Java 的 32 位无符号整数
- 哈希映射(整数,字符串[])在C++
- 三个有符号整数的哈希函数
- 可以返回基于字符串的整数范围的哈希函数
- 如何散列字符串?我需要把随机字符串转换成整数,放到哈希表中
- 哈希函数用于6个整数的良好排序/比较
- c++将十六进制md5哈希值转换为十进制整数
- 对一对整数(pair
)向量的哈希函数