首頁 > 後端開發 > C++ > AVX2和BMI2指令如何有效率地實現基於遮罩的左打包?

AVX2和BMI2指令如何有效率地實現基於遮罩的左打包?

Susan Sarandon
發布: 2024-12-29 19:34:11
原創
259 人瀏覽過

How Can AVX2 and BMI2 Instructions Efficiently Implement Left Packing Based on a Mask?

基於遮罩打包左的高效 AVX2 實作

與 SSE 不同,AVX 缺乏基於遮罩打包左的專用指令。然而,結合使用 AVX2 和 BMI2 指令可以有效地完成此任務。

使用AVX2 和BMI2

該方法利用vpermps (_mm256_permutevar8x32_ps) 指令,它執行車道交叉變量洗牌,並且pdep來自BMI2 的(_pde提供按位提取。

演算法步驟

  1. 使用表示所需排列的壓縮 3 位元索引建立一個常數。
  2. 使用 pdep 從mask。
  3. 將索引解壓縮為每個位元組一個。
  4. 將解壓縮的索引轉換為 vpermps 的控制遮罩。
  5. 使用 vpermps 執行變數洗牌。

實作詳細資料

下面的程式碼提供了AVX2 BMI2 中的實作:

#include <immintrin.h>

__m256 compress256(__m256 src, unsigned int mask)
{
  uint64_t expanded_mask = _pdep_u64(mask, 0x0101010101010101);  // unpack each bit to a byte
  expanded_mask *= 0xFF;    // mask |= mask<<1 | mask<<2 | ... | mask<<7;
  // ABC... -> AAAAAAAABBBBBBBBCCCCCCCC...: replicate each bit to fill its byte

  const uint64_t identity_indices = 0x0706050403020100;    // the identity shuffle for vpermps, packed to one index per byte
  uint64_t wanted_indices = _pext_u64(identity_indices, expanded_mask);

  __m128i bytevec = _mm_cvtsi64_si128(wanted_indices);
  __m256i shufmask = _mm256_cvtepu8_epi32(bytevec);

  return _mm256_permutevar8x32_ps(src, shufmask);
}
登入後複製

效能分析效能分析

效能分析

效能分析

效能分析

效能分析效能分析效能分析

效能分析

效能分析

效能分析效能分析🎜>此實作需要 6 uops,16c延遲。它有可能維持每 4 個週期一次迭代的吞吐量,從而保持多個迭代的運行。 替代方法對於 Zen 3 之前的 AMD CPU,pext/pdep速度非常慢,因此替代方法可能更好。對於 16 位元元素,可以採用 128 位元向量方法。對於 8 位元元素,可以使用涉及多個重疊塊的不同技術。

以上是AVX2和BMI2指令如何有效率地實現基於遮罩的左打包?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板