,,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指令集浮点组求和的更多信息,请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • 二分图匹配算法,二分图匹配方案数
  • 二分图匹配算法,二分图匹配方案数,二分图匹配实例代码及整理
  • sha是什么算法,sha-2算法
  • js两个数求和的函数,算法 两数之和
  • js两个数求和的函数,算法 两数之和,JS求解两数之和算法详解
  • js rc4加密解密,rc4加密算法详解
  • bcrypt加密算法,
  • ,,机器学习10大经典算法详解
  • ,,基于稀疏图上的Johnson算法的详解
  • prim算法求最小生成树代码,普里姆算法最小生成树C语言
  • prim算法求最小生成树代码,普里姆算法最小生成树C语言,Prim(普里姆)算法求最小生成树的思想及C语言实例讲解
  • c语言递归法求汉诺塔,汉诺塔递归算法c++语言
  • c语言递归法求汉诺塔,汉诺塔递归算法c++语言,C语言超详细讲解递归算法汉诺塔
  • Java二分法排序,java排序的几种方法,Java经典排序算法之二分插入排序详解
  • javan的阶乘的递归算法,递归算法实现阶乘
  • 留言与评论(共有 条评论)
       
    验证码: