C++avx256指令集加速实例

    科技2024-03-29  94

    背景

    avx256是x86cpu架构下实现SIMD(单指令多数据)的指令集。它能够利用cpu内部256bit的寄存器,同时对4位double或8位int类型的数操作,达到很好的加速效果。这里通过一个计算 π \pi π的实例来展示其威力: π = 4 ∫ 0 1 1 1 + x 2 d x \pi = 4\int_0^1\frac{1}{1+x^2}dx π=4011+x21dx linux系统下可以通过如下命令查看电脑是否支持avx256指令集:

    cat /proc/cpuinfo | grep flags

    sse4就表示该指令集。

    实例代码

    //g++ avx_pi.cpp -mavx -O2 #include <iostream> #include <ctime> #include <x86intrin.h> using namespace std; //正常的逐个累加运算 double compute_pi_naive(size_t dt){ double pi = 0.0; double delta = 1.0/dt; for (size_t i =0;i<dt;i++){ double x = (double)i/dt; pi += delta /(1+x*x); } return pi*4.0; } //利用avx256指令集 double compute_pi_avx256(size_t dt){ double pi = 0.0; double delta = 1.0/dt; __m256d ymm0,ymm1,ymm2,ymm3,ymm4; ymm0 = _mm256_set1_pd(1.0); ymm1 = _mm256_set1_pd(delta); ymm2 = _mm256_set_pd(delta*3,delta*2,delta,0.0); ymm4 = _mm256_setzero_pd(); for (int i = 0;i<dt-4;i+=4){ ymm3 = _mm256_set1_pd(i*delta); ymm3 = _mm256_add_pd(ymm3,ymm2); ymm3 = _mm256_mul_pd(ymm3,ymm3); ymm3 = _mm256_add_pd(ymm0,ymm3); ymm3 = _mm256_div_pd(ymm1,ymm3); ymm4 = _mm256_add_pd(ymm4,ymm3); } double tmp[4] __attribute__((aligned(32))); _mm256_store_pd(tmp,ymm4); pi += tmp[0]+tmp[1]+tmp[2]+tmp[3]; return pi*4.0; } int main(){ clock_t start,end; size_t dt = 134217728; double result1,result2; //普通函数计时 start = clock(); result1 = compute_pi_naive(dt); end = clock(); cout<<"naive:\n"<< result1 <<endl<<end- start <<endl; //avx256计时 start = clock(); result2 = compute_pi_avx256(dt); end = clock(); cout<<"avx256:\n" <<result2 <<endl<<end- start <<endl; return 0; }

    可以看出,速度提高了两倍多。

    Processed: 0.010, SQL: 8