Maison >développement back-end >C++ >Comment implémenter efficacement log2(__m256d) dans AVX2 ?

Comment implémenter efficacement log2(__m256d) dans AVX2 ?

DDD
DDDoriginal
2024-12-04 14:06:11193parcourir

How to Efficiently Implement log2(__m256d) in AVX2?

Implémentation efficace de log2(__m256d) dans AVX2

Introduction

Le __m256d intrinsèque _mm256_log2_pd (__m256da) n'est pas pris en charge au-delà des compilateurs Intel et ses performances sont compromises sur les processeurs AMD. Cet article vise à fournir une solution performante et multi-compilateur pour calculer log2() pour les vecteurs de doubles à l'aide du jeu d'instructions AVX2.

Approche

La méthode typique implique diviser log(a*b) en log(a) log(b) et ajuster le biais des exposants. Pour le cas de log2, le résultat est équivalent à l'exposant log2(mantisse). Comme la plage de mantisse (1,0 à 2,0) est limitée, une approximation polynomiale pour log2 (mantisse) peut être utilisée.

Considérations sur la précision

La précision de l'approximation influence l'erreur relative. Afin de minimiser l'erreur absolue ou relative maximale, les coefficients doivent être ajustés via un ajustement minimax plutôt que simplement en utilisant l'expansion en série de Taylor.

Vectorisation

Pour tirer parti de l'instruction AVX2 défini pour le traitement vectoriel, les étapes suivantes sont mises en œuvre :

  1. Extraire les bits d'exposant et les convertir en flottants après biais ajustement.
  2. Extraire la mantisse et modifiez-la pour une plage de [0,5, 1,0) avec des ajustements d'exposant.
  3. Utilisez une approximation polynomiale pour log(x) précis autour de x=1,0 à l'aide des instructions AVX2 avec FMA.
  4. Calculez le résultat final log2 en ajoutant l'exposant et le polynôme approximation.
  5. Incorporer une gestion spéciale pour les cas de sous-débordement, de débordement et de dénormalisation.

Améliorations des performances

Pour améliorer les performances :

  • Utilisez des polynômes d'ordre supérieur ou un rapport de polynômes pour une plus grande précision.
  • Utilisez les instructions AVX512 pour des capacités étendues, telles que l'extraction plus efficace des exposants et des mantisses.
  • Supprimez ou ajustez la vérification pour les cas particuliers si les valeurs sont connues pour être finies et positives.

Implémentation

L'implémentation ci-dessous utilise principes intrinsèques pour la vectorisation et instructions FMA pour une multiplication et une addition efficaces :

__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;
}

Conclusion

Cette implémentation fournit une solution efficace et portable pour les calculs log2() utilisant AVX2. En optimisant à la fois la vitesse et la précision, il offre une alternative multi-compilateur aux fonctions intrinsèques et peut améliorer considérablement les performances.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn