[英]What is the fastest way to combine 8 uint8_t into a single uintmax_t?
我正在尋找優化使用popcnt
來計算uint8_t
之間的差異的一段代碼。 我認為將8個uint8_t
合並為單個uintmax_t
並使用popcnt64
會更快,這樣popcnt操作的調用次數不必比必要的多8倍。 將8 uint8_t
饋入popcnt64
的最快方法是什么? 我可以使用某種鑄造嗎? 我應該利用位操作嗎? 我不了解C ++的內部工作原理,因此不確定執行此轉換的最快方法是什么。
假設您不關心字節序–您只想將uint8_t
視為uint64_t
並且不關心uint8_t
的順序–則可以使用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
並讓編譯器處理它就足夠了
請注意,從C ++調用popcnt
任何變體的最簡單方法是使用std::bitset::count
。 因此,您可以只編寫std::bitset<64>{my_u64}.count()
__popcnt64(my_u64)
而不是__builtin_popcountll(my_u64)
或__popcnt64(my_u64)
即可立即獲得可移植代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.