ホームページ > バックエンド開発 > C++ > AVX2 で log2(__m256d) を効率的に実装するにはどうすればよいですか?

AVX2 で log2(__m256d) を効率的に実装するにはどうすればよいですか?

DDD
リリース: 2024-12-04 14:06:11
オリジナル
194 人が閲覧しました

How to Efficiently Implement log2(__m256d) in AVX2?

AVX2 での log2(__m256d) の効率的な実装

概要

組み込み __m256d _mm256_log2_pd (__m256d a) は Intel コンパイラ以外ではサポートされておらず、AMD プロセッサではパフォーマンスが低下します。この記事は、AVX2 命令セットを使用して double のベクトルの log2() を計算するためのパフォーマンスの高いクロスコンパイラ ソリューションを提供することを目的としています。

アプローチ

一般的な方法には次のものが含まれます。 log(a*b) を log(a) log(b) に分割し、指数バイアスを調整します。 log2 の場合、結果は指数 log2(仮数部) に相当します。仮数の範囲 (1.0 ~ 2.0) が制限されているため、log2(仮数) の多項式近似を使用できます。

精度に関する考慮事項

近似の精度は次の影響を受けます。相対誤差。最大の絶対誤差または相対誤差を最小限に抑えるには、単にテイラー級数展開を使用するのではなく、ミニマックス フィッティングを通じて係数を調整する必要があります。

ベクトル化

AVX2 命令を利用するにはベクトル処理用に設定すると、次の手順が実装されます:

  1. 指数ビットを抽出し、それらを次の値に変換します。バイアス調整後の浮動小数点数。
  2. 仮数を抽出し、指数調整により [0.5, 1.0) の範囲に変更します。
  3. x=1.0 付近で正確な log(x) の多項式近似を利用します。 FMA で AVX2 命令を使用します。
  4. 指数と多項式近似。
  5. アンダーフロー、オーバーフロー、および非正規化の場合の特別な処理を組み込みます。

パフォーマンスの強化

パフォーマンスを向上するには:

  • 高次を使用多項式または多項式の比を使用して精度を高めます。
  • 指数や仮数をより効率的に抽出するなど、拡張機能のために AVX512 命令を利用します。
  • 値が既知である場合、特殊な場合のチェックを削除または調整します。有限であることと、

実装

以下の実装では、ベクトル化に組み込み関数を使用し、乗算と加算を効率的に行うために FMA 命令を使用します。

__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;
}
ログイン後にコピー

結論

この実装は以下を提供しますAVX2 を使用した log2() 計算のための効率的で移植可能なソリューション。速度と精度の両方を最適化することで、組み込み関数に代わるクロスコンパイラーを提供し、パフォーマンスを大幅に向上させることができます。

以上がAVX2 で log2(__m256d) を効率的に実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート