簡體   English   中英

將8 uint8_t合並為單個uintmax_t的最快方法是什么?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM