Mise en œuvre efficace d'AVX2 pour l'emballage laissé en fonction d'un masque
Contrairement à SSE, AVX ne dispose pas d'instructions dédiées pour l'emballage laissé en fonction d'un masque. Cependant, une combinaison d'instructions AVX2 et BMI2 peut être utilisée pour réaliser cette tâche efficacement.
Utilisation d'AVX2 et BMI2
L'approche exploite l'instruction vpermps (_mm256_permutevar8x32_ps), qui effectue un brassage variable de croisement de voies, et le pdep (_pdep_u64) instruction de BMI2, qui fournit une extraction au niveau du bit.
Étapes de l'algorithme
Détails de mise en œuvre
Le code ci-dessous fournit une implémentation dans 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); }
Analyse des performances
Cette implémentation entraîne 6 uops avec une latence de 16c. Il peut potentiellement supporter un débit d'une itération tous les 4 cycles, gardant plusieurs itérations en vol.
Approches alternatives
Pour les processeurs AMD antérieurs à Zen 3, pext/pdep sont très lents, des approches alternatives peuvent donc être préférables. Pour les éléments de 16 bits, une approche vectorielle de 128 bits pourrait être utilisée. Pour les éléments de 8 bits, une technique différente impliquant plusieurs morceaux superposés peut être utilisée.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!