AVX2 中 log2(__m256d) 的高效實現
簡介
簡介方法典型方法包括將 log(a*b) 除以 log(a) log(b) 並調整指數偏差。對於 log2 的情況,結果相當於指數 log2(尾數)。由於尾數範圍(1.0 到 2.0)有限,可以使用 log2(尾數) 的多項式逼近。
精準度注意事項逼近的精準度影響相對誤差。為了最小化最大絕對或相對誤差,應透過極小極大擬合來調整係數,而不是簡單地使用泰勒級數展開。
矢量化性能增強
實現
__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中文網其他相關文章!