Heim >Backend-Entwicklung >C++ >Wie implementiert man log2(__m256d) effizient in AVX2?

Wie implementiert man log2(__m256d) effizient in AVX2?

DDD
DDDOriginal
2024-12-04 14:06:11195Durchsuche

How to Efficiently Implement log2(__m256d) in AVX2?

Effiziente Implementierung von log2(__m256d) in AVX2

Einführung

Das intrinsische __m256d _mm256_log2_pd (__m256d a) wird nicht über Intel-Compiler hinaus unterstützt und seine Leistung ist auf AMD-Prozessoren beeinträchtigt. Ziel dieses Artikels ist es, eine leistungsstarke und kompilerübergreifende Lösung zur Berechnung von log2() für Vektoren von Doubles mithilfe des AVX2-Befehlssatzes bereitzustellen.

Ansatz

Die typische Methode umfasst Teilen von log(a*b) in log(a) log(b) und Anpassen der Exponentenverzerrung. Im Fall von log2 entspricht das Ergebnis dem Exponenten log2(Mantisse). Da der Mantissenbereich (1,0 bis 2,0) begrenzt ist, kann eine polynomische Näherung für log2 (Mantisse) verwendet werden.

Überlegungen zur Genauigkeit

Die Genauigkeit der Näherung beeinflusst der relative Fehler. Um den maximalen absoluten oder relativen Fehler zu minimieren, sollten die Koeffizienten durch Minimax-Anpassung angepasst werden, anstatt einfach die Taylor-Reihenentwicklung zu verwenden.

Vektorisierung

Zur Nutzung der AVX2-Anweisung Für die Vektorverarbeitung festgelegt, werden die folgenden Schritte implementiert:

  1. Exponentenbits extrahieren und nach Vorspannung in Gleitkommazahlen umwandeln Anpassung.
  2. Extrahieren Sie die Mantisse und modifizieren Sie sie für einen Bereich von [0,5, 1,0) mit Exponentenanpassungen.
  3. Verwenden Sie mithilfe von AVX2-Anweisungen eine Polynomnäherung für log(x) mit einer Genauigkeit um x=1,0 mit FMA.
  4. Berechnen Sie das endgültige log2-Ergebnis durch Addition des Exponenten und des Polynoms Näherung.
  5. Besondere Behandlung für Unterlauf-, Überlauf- und Denormalfälle integrieren.

Leistungsverbesserungen

Um die Leistung zu verbessern:

  • Verwenden Sie Polynome höherer Ordnung oder ein Verhältnis von Polynomen für größere Präzision.
  • Verwenden Sie AVX512-Anweisungen für erweiterte Funktionen, wie z. B. das effizientere Extrahieren von Exponenten und Mantissen.
  • Entfernen oder passen Sie die Prüfung für Sonderfälle an, wenn bekannt ist, dass Werte endlich und positiv sind.

Implementierung

Die folgende Implementierung verwendet Intrinsics für Vektorisierung und FMA-Anweisungen für effiziente Multiplikation und Addition:

__m256d Log2(__m256d x) {
  // Extract exponent and adjust bias
  const __m256i exps64 = _mm256_srli_epi64(_mm256_and_si256(gDoubleExpMask, _mm256_castpd_si256(x)), 52);
  const __m256i exps32_avx = _mm256_permutevar8x32_epi32(exps64, gTo32bitExp);
  const __m128i exps32_sse = _mm256_castsi256_si128(exps32_avx);
  const __m128i normExps = _mm_sub_epi32(exps32_sse, gExpNormalizer);
  const __m256d expsPD = _mm256_cvtepi32_pd(normExps);

  // Prepare mantissa
  const __m256d y = _mm256_or_pd(_mm256_castsi256_pd(gDoubleExp0),
    _mm256_andnot_pd(_mm256_castsi256_pd(gDoubleExpMask), x));

  // Calculate t=(y-1)/(y+1) and t**2
  const __m256d tNum = _mm256_sub_pd(y, gVect1);
  const __m256d tDen = _mm256_add_pd(y, gVect1);
  const __m256d t = _mm256_div_pd(tNum, tDen);
  const __m256d t2 = _mm256_mul_pd(t, t); // t**2

  // Calculate terms and final log2
  const __m256d t3 = _mm256_mul_pd(t, t2); // t**3
  const __m256d terms01 = _mm256_fmadd_pd(gCoeff1, t3, t);
  const __m256d t5 = _mm256_mul_pd(t3, t2); // t**5
  const __m256d terms012 = _mm256_fmadd_pd(gCoeff2, t5, terms01);
  const __m256d t7 = _mm256_mul_pd(t5, t2); // t**7
  const __m256d terms0123 = _mm256_fmadd_pd(gCoeff3, t7, terms012);
  const __m256d t9 = _mm256_mul_pd(t7, t2); // t**9
  const __m256d terms01234 = _mm256_fmadd_pd(gCoeff4, t9, terms0123);
  const __m256d log2_y = _mm256_mul_pd(terms01234, gCommMul);
  const __m256d log2_x = _mm256_add_pd(log2_y, expsPD);

  return log2_x;
}

Fazit

Diese Implementierung bietet eine effiziente und portable Lösung für log2()-Berechnungen mit AVX2. Durch die Optimierung sowohl der Geschwindigkeit als auch der Genauigkeit bietet es eine kompilerübergreifende Alternative zu intrinsischen Funktionen und kann die Leistung erheblich verbessern.

Das obige ist der detaillierte Inhalt vonWie implementiert man log2(__m256d) effizient in AVX2?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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