Heim > Backend-Entwicklung > C++ > Wie können AVX2- und BMI2-Anweisungen die linke Packung basierend auf einer Maske effizient implementieren?

Wie können AVX2- und BMI2-Anweisungen die linke Packung basierend auf einer Maske effizient implementieren?

Susan Sarandon
Freigeben: 2024-12-29 19:34:11
Original
242 Leute haben es durchsucht

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

Effiziente AVX2-Implementierung zum Packen von Links basierend auf einer Maske

Im Gegensatz zu SSE fehlt AVX eine spezielle Anweisung zum Packen von Links basierend auf einer Maske. Allerdings kann eine Kombination aus AVX2- und BMI2-Anweisungen verwendet werden, um diese Aufgabe effizient zu lösen.

Verwendung von AVX2 und BMI2

Der Ansatz nutzt die vpermps-Anweisung (_mm256_permutevar8x32_ps), das einen spurübergreifenden Variablen-Shuffle durchführt, und das pdep (_pdep_u64) Anweisung von BMI2, die eine bitweise Extraktion ermöglicht.

Algorithmusschritte

  1. Erstellen Sie eine Konstante mit gepackten 3-Bit-Indizes, die die gewünschte Permutation darstellen.
  2. Verwenden Sie pdep, um die relevanten Indizes aus dem zu extrahieren mask.
  3. Entpacken Sie die Indizes auf einen pro Byte.
  4. Konvertieren Sie die entpackten Indizes in eine Steuermaske für vpermps.
  5. Führen Sie die Variablenmischung mit vpermps durch.

Umsetzung Details

Der folgende Code stellt eine Implementierung in AVX2 BMI2 bereit:

#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);
}
Nach dem Login kopieren

Leistungsanalyse

Diese Implementierung verursacht 6 Uops mit 16c Latenz. Es kann möglicherweise einen Durchsatz von einer Iteration pro 4 Zyklen aufrechterhalten und mehrere Iterationen im Flug halten.

Alternative Ansätze

Für AMD-CPUs vor Zen 3, pext/pdep sind sehr langsam, daher sind alternative Ansätze möglicherweise vorzuziehen. Für 16-Bit-Elemente könnte ein 128-Bit-Vektoransatz verwendet werden. Für 8-Bit-Elemente kann eine andere Technik mit mehreren überlappenden Blöcken verwendet werden.

Das obige ist der detaillierte Inhalt vonWie können AVX2- und BMI2-Anweisungen die linke Packung basierend auf einer Maske effizient implementieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage