[发明专利]一种基于INTEL AVX指令集的浮点峰值计算吞吐测试方法有效
申请号: | 201810014687.2 | 申请日: | 2018-01-08 |
公开(公告)号: | CN108268349B | 公开(公告)日: | 2021-05-18 |
发明(设计)人: | 李艳兵;路凯林;蒋钟文 | 申请(专利权)人: | 青岛雷神科技股份有限公司 |
主分类号: | G06F11/22 | 分类号: | G06F11/22;G06F9/30;G06F9/38 |
代理公司: | 青岛致嘉知识产权代理事务所(普通合伙) 37236 | 代理人: | 单虎 |
地址: | 266000 山东省青岛市崂山*** | 国省代码: | 山东;37 |
权利要求书: | 查看更多 | 说明书: | 查看更多 |
摘要: | |||
搜索关键词: | 一种 基于 intel avx 指令 浮点 峰值 计算 吞吐 测试 方法 | ||
1.一种基于INTEL AVX指令集的浮点峰值计算吞吐测试方法,其特征在于,包括以下步骤:
步骤1:AVX 128Bit ADD/Sub;
使用AVX组合浮点计算,首先要对寄存器进行加载操作,将相应数据加载到相应寄存器,这里使用128bit SIMD指令将加法要做的数值加载:const__m128d add0=_mm_set1_pd,vmovaps指令可把4个对准的单精度值传送到xmm寄存器或者内存,vmovupd可把4个不对准的单精度值传送到xmm寄存器或者内存,将数值送入128bit xmm寄存器后,便可使用加法与减法指令执行Add或者Sub;
使用add_ps语句将add0的数值与r0-r7的数值进行加法计算
r0=_mm_add_ps(r0,add0);
r1=_mm_add_ps(r1,add0);
r2=_mm_add_ps(r2,add0);
r3=_mm_add_ps(r3,add0);
r4=_mm_add_ps(r4,add0);
r5=_mm_add_ps(r5,add0);
r6=_mm_add_ps(r6,add0);
r7=_mm_add_ps(r7,add0);
使用sub_ps语句将sub0的数值与r0-r7的数值进行组合浮点减法计算
r0=_mm_sub_ps(r0,sub0);
r1=_mm_sub_ps(r1,sub0);
r2=_mm_sub_ps(r2,sub0);
r3=_mm_sub_ps(r3,sub0);
r4=_mm_sub_ps(r4,sub0);
r5=_mm_sub_ps(r5,sub0);
r6=_mm_sub_ps(r6,sub0);
r7=_mm_sub_ps(r7,sub0);
编译器将使用SIMD模式编译为vaddps xmm0,xmm6,xmm4的语句或者vsubps xmm0,xmm6,xmm4的语句,
这样就构成了AVX-128向量计算加法与减法的基本计算部分;
步骤2:AVX 128bit Mul;
Mul便是乘法计算的简写,在进行矢量乘法的时候,我们依旧要将数据装载入SIMD寄存器中,且保证对应的单精度和双精度占满SIMD寄存器,如计算32位单精度浮点数时,一个xmm寄存器需打包4个单精度浮点数和2个双精度浮点数乘法计算部分仍然为之前的数据加载,加载至mul0、mul1两个寄存器中,但计算部分调用12个寄存器,进行4组乘法计算,对mul0的两组,对mul1的两组
r0=_mm_mul_ps(r0,mul0);
r1=_mm_mul_ps(r1,mul0);
r2=_mm_mul_ps(r2,mul0);
r3=_mm_mul_ps(r3,mul0);
r4=_mm_mul_ps(r4,mul0);
r5=_mm_mul_ps(r5,mul0);
r6=_mm_mul_ps(r6,mul0);
r7=_mm_mul_ps(r7,mul0);
r8=_mm_mul_ps(r8,mul0);
r9=_mm_mul_ps(r9,mul0);
rA=_mm_mul_ps(rA,mul0);
rB=_mm_mul_ps(rB,mul0);
r0=_mm_mul_ps(r0,mul1);
r1=_mm_mul_ps(r1,mul1);
r2=_mm_mul_ps(r2,mul1);
r3=_mm_mul_ps(r3,mul1);
r4=_mm_mul_ps(r4,mul1);
r5=_mm_mul_ps(r5,mul1);
r6=_mm_mul_ps(r6,mul1);
r7=_mm_mul_ps(r7,mul1);
r8=_mm_mul_ps(r8,mul1);
r9=_mm_mul_ps(r9,mul1);
rA=_mm_mul_ps(rA,mul1);
rB=_mm_mul_ps(rB,mul1);
r0=_mm_mul_ps(r0,mul0);
r1=_mm_mul_ps(r1,mul0);
r2=_mm_mul_ps(r2,mul0);
r3=_mm_mul_ps(r3,mul0);
r4=_mm_mul_ps(r4,mul0);
r5=_mm_mul_ps(r5,mul0);
r6=_mm_mul_ps(r6,mul0);
r7=_mm_mul_ps(r7,mul0);
r8=_mm_mul_ps(r8,mul0);
r9=_mm_mul_ps(r9,mul0);
rA=_mm_mul_ps(rA,mul0);
rB=_mm_mul_ps(rB,mul0);
r0=_mm_mul_ps(r0,mul1);
r1=_mm_mul_ps(r1,mul1);
r2=_mm_mul_ps(r2,mul1);
r3=_mm_mul_ps(r3,mul1);
r4=_mm_mul_ps(r4,mul1);
r5=_mm_mul_ps(r5,mul1);
r6=_mm_mul_ps(r6,mul1);
r7=_mm_mul_ps(r7,mul1);
r8=_mm_mul_ps(r8,mul1);
r9=_mm_mul_ps(r9,mul1);
rA=_mm_mul_ps(rA,mul1);
rB=_mm_mul_ps(rB,mul1);
编译器将使用SIMD模式编译为vmulps xmm0,xmm6,xmm4的语句,这样就构成了AVX-128向量计算乘法的基本计算部分;
步骤3:AVX 128Bit FMA;
融合乘加指令集分两种,基于Intel处理器支持的为FMA3,基于AMD Bulldozer和Piledriver架构处理器的为FMA4指令集,这两者之间的区别在于支持的操作数有不同,FMA3指令可实现三操作数的融合乘加指令,即完成单指令A=(A+B)*C的计算,四操作数的FMA4指令,即A=(B+C)*D的计算,这样在运作中一次调用的寄存器数量也不同;
FMA3 128bit
同时FMA3主要有4种融合模式,即融合乘加Vfmadd,乘减融合Vfmsub,负的乘加融合Vfnmadd(-(a*b)+c),负的乘减融合Vfnmsub(-(a*b)-c)
针对三操作数的浮点计算算法,将融合乘加与负的融合乘加指令结合,让CPU执行基于FMA3指令集的融合乘加与负的融合乘加计算,同时加载命令不变,依旧是使用_mm_set1_ps指令,使用融合乘加FMA3需要同时执行三个操作数:
r0=_mm_fmadd_ps(mul0,mul1,r0);
r1=_mm_fmadd_ps(mul0,mul1,r1);
r2=_mm_fmadd_ps(mul0,mul1,r2);
r3=_mm_fmadd_ps(mul0,mul1,r3);
r4=_mm_fmadd_ps(mul0,mul1,r4);
r5=_mm_fmadd_ps(mul0,mul1,r5);
r6=_mm_fmadd_ps(mul0,mul1,r6);
r7=_mm_fmadd_ps(mul0,mul1,r7);
r8=_mm_fmadd_ps(mul0,mul1,r8);
r9=_mm_fmadd_ps(mul0,mul1,r9);
rA=_mm_fmadd_ps(mul0,mul1,rA);
rB=_mm_fmadd_ps(mul0,mul1,rB);
这里Vfmaddps语句将mul0、mul1和寄存器r0的数据进行融合乘加等价于r0=mul0*mul1+r0将结果存入r0到rb一共12个寄存器中,加上原本mul0与mul1的两个寄存器,一共占用14个寄存器,另一部分使用负的融合乘加指令Vfnmadd替换Vfmadd即可;
FMA4 128bit
FMA4指令的代码不同于FMA3的Vfmaddps这类语句,而是_mm_nmacc_ps和_mm_macc_ps这样的语句来执行融合乘加和负的融合乘加操作;
步骤4:AVX 128Bit ADD+Mul;
本步骤采用上述的乘法和加法的部分;
步骤5:AVX 256Bit ADD/Sub;
const__m256mul0=_mm256_set1_ps
const__m256mul1=_mm256_set1_ps,定义装载256位寄存器,同时计算部分要使用256bit定义,加法语句为:
r0=_mm256_add_ps(r0,add0);
步骤6,AVX 256Bit Mul;
同AVX128Bit Mul内容,需在_mm_mul前加入256进行定义即可;
步骤7,AVX 256Bit FMA;
同AVX128Bit FMA内容,需在_mm_fmadd_ps前加入256进行定义即可;
步骤8,AVX 256Bit ADD+Mul;
同AVX128Bit ADD与Mul内容,需在_mm_add_ps和_mm_sub_ps前加入256进行定义即可;
步骤9,AVX 512Bit ADD/Sub;
采用512位定义的AVX512 C++语言模式,即_mm512_add_ps和_mm512_sub_ps;
步骤10,AVX 512Bit Mul;
采用512位定义的AVX512 C++语言模式,即_mm512_mul_ps;
步骤11,AVX 512Bit ADD+Mul;
使用乘法与加法结合的形式,乘法和加法都分别计算,使用_mm512_add_ps和_mm512_mul_ps指令执行;
步骤12,AVX 512Bit FMA;
将步骤11的Mul、ADD乘法加法指令分别执行,改用FMA指令执行,即_mm512_fmadd_ps;
步骤13,计算过程自动迭代和纳秒级计时;
从pentium开始,很多80x86微处理器都引入TSC,一个用于时间戳计数器的64位的寄存器,它在每个时钟信号到来时加一;计算部分需要while—iterations循环迭代,迭代上十亿次,定义struct结构体关键字,results是定义的结果,具体声明了拥有2个成员的结构体,分别为双精度的flops值和sum总和,flops值即浮点操作次数,定义相应的类名:benchmark,即测试结果,最终表示为Gflops/每秒,在固定的时间内即可,void run将执行线程和时间的值输入,同时每次迭代会有多个block进行计算,各个线程同时记录返回值,最终浮点操作次数=iterations*flops_per_iteration*block_size/seconds,iterations为迭代次数,flops_per_iteration为每次迭代的浮点操作次数,block_size为数据块大小,seconds为秒,以上为测试线程的定义,确定计算的量和flops的结果,将结果除以10亿即为Gflops;
步骤14,针对不同处理器架构:
由于不同时代的处理器支持的指令集不同,所以应当选择合适的指令集编译文件进行测试,以防运行出错,所以针对目前主流CPU,主要分为7个大类:
Core2-SSE 128bit体系
Sandy bridge-AVX体系
Haswell-AVX2 FMA3体系
AMD Bulldozer AVX FMA4体系
AMD Piledriver AVX2 FMA4体系
Intel purley AVX512 FMA3体系
AMD Zen AVX2 FMA3体系
验证处理器是否支持相应指令集才可运行,运行CPUID识别程序即可,识别是否支持AVX-AVX2-FMA3-FMA4-AVX512指令集,CPU信息现在存储于EAX寄存器,检测AVX和FMA指令集;通过读取EAX寄存器相应地址,获取返回值后识别,若不支持相应指令集,则不运行该指令集的浮点计算测试;
步骤15,单线程测试+多线程调用:
该计算程序的执行默认将执行单线程运算,C++11新标准中引入C++11新标准中引入四个头文件来支持多线程编程,他们分别是atomic,thread,mutex,condition_variable和future;语句std::thread::hardware_concurrency,返回实现支持的并发线程数;当确认支持的线程并发数之后,需要使用std::thread t[num_threads];建立相应数量的线程;
步骤16,显示出测试结果:
当某个计算步骤迭代完成后,将由相应的计算次数与计算的时间进行除法,输出对应的浮点计算次数。
该专利技术资料仅供研究查看技术是否侵权等信息,商用须获得专利权人授权。该专利全部权利属于青岛雷神科技股份有限公司,未经青岛雷神科技股份有限公司许可,擅自商用是侵权行为。如果您想购买此专利、获得商业授权和技术合作,请联系【客服】
本文链接:http://www.vipzhuanli.com/pat/books/201810014687.2/1.html,转载请声明来源钻瓜专利网。
- 上一篇:接口测试方法、装置、移动终端及存储介质
- 下一篇:控制方法及相关产品