AVX2指令集优化浮点数组求和算法

AVX2指令集优化浮点数组求和算法

本文主要为大家介绍AVX2指令集优化浮点组求和算法。有需要的朋友可以借鉴一下,希望能有所帮助。祝大家进步很大,早日升职加薪。

目录

I av x2指令集简介描述运算性能II。代码实现0。数据生成1。通用阵列求和2。AVX2指令集求和:单精度浮点(float)3。AVX2指令集求和:双精度浮点(double) III。性能测试环境,计时方法,测试内容,性能测试,第一次测试,第二次测试四。摘要

一、AVX2指令集介绍

AVX2是SIMD(single instruction multi data,单指令多数据)指令集,支持在一个指令周期内同时操作256位存储器。包括乘法、加法、位运算等功能。下面附上的是英特尔官方网站用户文档。

英特尔内部指南

这次需要用到的指令有_ _ M256I _ MM 256 _ Add _ PD (_ _ M256IA,_ _ M256IB),_ _ M256I _ MM 256 _ Add _ PS等。(P代表精度,S代表单精度,D代表双精度)

它们可以一次获取256位内存,并以浮点形式增加32/64位。下面附上官网说明。

Synopsis

__m256d _mm256_add_pd (__m256d a,__m256d b)

#包含immintrin.h

指令:vaddpd ymm,ymm,ymm

CPUID标志:AVX

Description

将a和b中打包的双精度(64位)浮点元素相加,结果存储在dst中。

Operation

对于j :=0到3

i :=j*64

dst[i 63:i] :=a[i 63:i] b[i 63:i]

结束

dst[最大值:256] :=0

Performance

建筑吞吐量(CPI)冰湖

二、代码实现

0. 数据生成

为了比较结果,我们生成从1到n的算术级数。这里,模板用于兼容不同的数据类型。由于AVX2指令集一次要操作多个数据,为了防止内存访问越界,我们将大小扩展到256整数倍位,即32字节的整数倍。

uint64_t低位(uint64_t x)

{

返回x(-x);

}

uint64_t extTo2Power(uint64_t n,int i)//arraysize数据大小

{

while(低位(n) i)

n=low bit(n);

返回n;

}

模板类型名T

T* getArray(uint64_t大小)

{

uint 64 _ T ExSize=ext to 2 power(size,32/sizeof(T));

T * arr=new T[ExSize];

for(uint 64 _ t I=0;I尺寸;我)

arr[I]=I ^ 1;

for(uint 64 _ t I=size;我ExSize我)

arr[I]=0;

返回arr

}

1. 普通数组求和

为了比较性能差异,我们首先实现一个普通的数组和。这里也用到了模板。

模板类型名T

T simpleSum(T* arr,uint64_t size)

{

t sum=0;

for(uint 64 _ t I=0;I尺寸;我)

sum=arr[I];

返回总和;

}

2. AVX2指令集求和:单精度浮点(float)

这里我们预打开avx2的一个整形变量,一次从数组中取出8个32位浮点,加到这个变量中,最后将这8个32位浮点求和。

float avx2Sum(float* arr,uint64_t size)

{

float sum[8]={ 0 };

_ _ m256 sum 256=_ mm 256 _ set zero _ PS();

_ _ m256 load 256=_ mm 256 _ set zero _ PS();

for(uint 64 _ t I=0;I尺寸;i=8)

{

load 256=_ mm 256 _ loadu _ PS(arr[I]);

sum256=_mm256_add_ps(sum256,load 256);

}

sum256=_mm256_hadd_ps(sum256,sum 256);

sum256=_mm256_hadd_ps(sum256,sum 256);

_mm256_storeu_ps(sum,sum 256);

总和[0]=总和[4];

返回sum[0];

}

这里的Hadd是水平加法,其具体实现类似于下图,可以帮助我们实现数组内的求和:

3. AVX2指令集求和:双精度浮点(double)

double avx2Sum(double* arr,uint64_t size)

{

double sum[4]={ 0 };

_ _ m256d sum 256=_ mm 256 _ set zero _ PD();

_ _ m256d load 256=_ mm 256 _ set zero _ PD();

for(uint 64 _ t I=0;I尺寸;i=4)

{

load 256=_ mm 256 _ loadu _ PD(arr[I]);

sum256=_mm256_add_pd(sum256,load 256);

}

sum256=_mm256_hadd_pd(sum256,sum 256);

_mm256_storeu_pd(sum,sum 256);

总和[0]=总和[2];

返回sum[0];

}

三、性能测试

测试环境

设备描述英特尔酷睿i9-9880H 8核2.3 GHz内存DDR4-2400MHz双通道32 gbc编译器Clang-1300.0.29.30

计时方式

利用chrono库获取系统时钟,计算运行时间,精确到毫秒级。

uint64_t getTime()

{

uint 64 _ t time ms=STD:chrono:duration _ cast STD:chrono:毫秒(std:chrono:system_clock:now()。time_since_epoch())。count();

返回时间ms;

}

测试内容

求和1到1e9,答案应该是50000000050000000。分别测试float和double。

uint64 _ t N=1e9

//比较普通加法和avx2加法的性能

uint64_t开始,结束;

//测试浮点

cout compare float sum: endl;

float * arr 3=getArrayfloat(N);

start=getTime();

float sum3=simpleSum(arr3,N);

end=getTime();

cout float simple sum time: end-start endl;

cout float simple sum sum: sum 3 endl;

start=getTime();

sum3=avx2Sum(arr3,N);

end=getTime();

cout float avx 2 sum time: end-start endl;

cout float avx 2 sum sum: sum 3 endl;

删除[]arr 3;

cout endl endl

//测试双精度

cout compare double sum: endl;

double * arr 4=getArraydouble(N);

start=getTime();

double sum4=simpleSum(arr4,N);

end=getTime();

cout double simple sum time: end-start endl;

cout double simple sum sum: sum 4 endl;

start=getTime();

sum4=avx2Sum(arr4,N);

end=getTime();

cout double avx 2 sum time: end-start endl;

cout double avx 2 sum sum: sum 4 endl;

删除[]arr 4;

cout endl endl

进行性能测试

第一次测试

测试命令

g -mavx2 avx_big_integer.cpp。/a.out

试验结果

方法耗时(ms)AVX2加法单精度615普通加法单精度2229AVX2加法双精度1237普通加法双精度2426

这里可以看到,在单精度下出现了明显的误差,并且由于普通求和与avx2求和的加法顺序不同,误差值也不同。

第二次测试

测试命令

现在让我们打开O2编译优化,试一试:

g -O2 -mavx2 avx_big_integer.cpp。/a.out

试验结果

方法耗时(ms)AVX2加法32位244普通加法32位1012AVX2加法64位476普通加法64位1292

我们发现,相比上次测试整形,开启O2优化后,通过AVX2指令集添加,浮点型有了明显的提升。

四、总结

可以看出,在进行浮点运算时,用avx2指令集进行并行优化可以得到比整形更好的结果。

个人猜测原因:

浮点加法器比整形加法器复杂得多,流水线操作的效果也没有那么明显。有可能CPU中的浮点加法器比整形加法器少,导致O2优化在乱序执行时优化效果不如整形理想。AVX2指令集可能专门针对浮点运算进行了优化,使得浮点运算的性能更接近整形运算。

以上是AVX2指令集优化浮点组求和算法的详细内容。有关AVX2指令集浮点组求和的更多信息,请关注我们的其他相关文章!

AVX2指令集优化浮点数组求和算法