Pelaksanaan log2(__m256d) yang Cekap dalam AVX2
Pengenalan
__mm256d log intrinsik (__m256d a) tidak disokong melebihi penyusun Intel dan prestasinya terjejas pada pemproses AMD. Artikel ini bertujuan untuk menyediakan penyelesaian berprestasi dan pengkompil silang untuk mengira log2() bagi vektor beregu menggunakan set arahan AVX2.
Pendekatan
Kaedah biasa melibatkan membahagikan log(a*b) kepada log(a) log(b) dan melaraskan pincang eksponen. Untuk kes log2, hasilnya bersamaan dengan log eksponen2(mantissa). Memandangkan julat mantissa (1.0 hingga 2.0) adalah terhad, anggaran polinomial untuk log2(mantissa) boleh digunakan.
Pertimbangan Ketepatan
Ketepatan anggaran mempengaruhi ralat relatif. Untuk meminimumkan ralat mutlak atau relatif maksimum, pekali harus ditala melalui pemasangan minimax dan bukannya hanya menggunakan pengembangan siri Taylor.
Vectorization
Untuk memanfaatkan arahan AVX2 ditetapkan untuk pemprosesan vektor, langkah berikut dilaksanakan:
Peningkatan Prestasi
Untuk meningkatkan prestasi:
Pelaksanaan
Pelaksanaan di bawah menggunakan intrinsik untuk vektorisasi dan arahan FMA untuk pendaraban dan penambahan yang cekap:
__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; }
Kesimpulan
Pelaksanaan ini menyediakan penyelesaian yang cekap dan mudah alih untuk log2() pengiraan menggunakan AVX2. Dengan mengoptimumkan kedua-dua kelajuan dan ketepatan, ia menawarkan alternatif pengkompil silang kepada fungsi intrinsik dan boleh meningkatkan prestasi dengan ketara.
Atas ialah kandungan terperinci Bagaimana untuk Melaksanakan log2(__m256d) dengan Cekap dalam AVX2?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!