首頁 >後端開發 >C++ >如何在AVX2中高效實現log2(__m256d)?

如何在AVX2中高效實現log2(__m256d)?

DDD
DDD原創
2024-12-04 14:06:11195瀏覽

How to Efficiently Implement log2(__m256d) in AVX2?

AVX2 中 log2(__m256d) 的高效實現

簡介

簡介

方法

典型方法包括將 log(a*b) 除以 log(a) log(b) 並調整指數偏差。對於 log2 的情況,結果相當於指數 log2(尾數)。由於尾數範圍(1.0 到 2.0)有限,可以使用 log2(尾數) 的多項式逼近。

精準度注意事項

逼近的精準度影響相對誤差。為了最小化最大絕對或相對誤差,應透過極小極大擬合來調整係數,而不是簡單地使用泰勒級數展開。

矢量化

    利用AVX2 指令設定為向量處理,實現以下步驟:
  1. 提取指數位並將其轉換為浮指數位並將其轉換為浮點數偏差調整。
  2. 提取尾數並透過指數調整將其修改為 [0.5, 1.0) 範圍。
  3. 使用 AVX2 對 log(x) 進行多項式近似,精確到 x=1.0使用 FMA 進行說明。
  4. 透過添加指數和多項式近似。
結合下溢、溢出和非正規情況的特殊處理。

性能增強

    提高性能:
  • 使用高階多項式或比率多項式以獲得更高的精度。
  • 利用 AVX512 指令實現擴充功能,例如更有效地擷取指數和尾數。
如果已知值是有限的,則刪除或調整對特殊情況的檢查

實現

__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;
}
下面的實現使用內部函數進行向量化,並使用FMA 指令進行高效乘法和加法:

結論

這個實作提供了一個高效且使用 AVX2 進行 log2() 計算的便攜式解決方案。透過優化速度和準確性,它提供了內部函數的交叉編譯器替代方案,並且可以顯著提高效能。

以上是如何在AVX2中高效實現log2(__m256d)?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn