我希望优化一段使用popcnt
计算uint8_t
之间的差异的代码,我认为将8个uint8_t
合并成一个uintmax_t
并使用popcnt64
会更快,这样就不必在必要时调用8x。将8 uint8_t
输入popcnt64
的最快方法是什么?我能用某种铸造法吗?我应该使用位操作吗?我不知道C++的内部工作原理,所以我不确定最快的方法是如何进行这种转换。
发布于 2018-02-13 21:23:20
假设您不关心endianness --您只想把uint8_t
s当作一个uint64_t
,而不关心uint8_t
s的顺序--那么您只需要使用std::memcpy
来进行类型双关:
std::uint64_t combine(std::array<std::uint8_t, 8> b) {
static_assert(sizeof(b) == sizeof(std::uint64_t));
static_assert(std::is_trivially_copyable_v<std::uint64_t>);
static_assert(std::is_trivially_copyable_v<decltype(b)>);
std::uint64_t result;
std::memcpy(&result, b.data(), sizeof(result));
return result;
}
生成组件只返回参数:
combine(std::array<unsigned char, 8ul>): # @combine(std::array<unsigned char, 8ul>)
mov rax, rdi
ret
使用任何其他的类型双关使它,所以你必须担心严格的混叠规则或类型对齐。只要使用std::memcpy
并让编译器处理它就足够容易了
请注意,从popcnt
调用C++的任何变体的最简单方法是使用std::bitset::count
。因此,您可以不使用__builtin_popcountll(my_u64)
或__popcnt64(my_u64)
,只需编写std::bitset<64>{my_u64}.count()
即可立即获得可移植代码。
https://stackoverflow.com/questions/48775192
复制相似问题