飞腾(ARM V8)平台实现FFT

最近在做飞腾上的FFT优化,记录一下以后用。

目前实现了基2FFT,使用arm提供的neon接口做了并行计算。算法原理网上很多,这里就不讲了,记录复数正向优化方法。

优化思路:

  1. 第一层蝶形计算:

第一层的蝶形因子都是1,蝶形下半部分就无需乘蝶形因子,直接与蝶形上半部分做加减运算即可。

由于第一层蝶形上下部分跨度为1(即连续),直接加载4个数据到向量寄存器无法实现并行计算,改用vld2q_f32()对输入信号进行加载,存入到float32x4x2类型的变量中。具体形式如下图:

第一行4个数据为蝶形的上半部分,第二行四个数据为蝶形的下半部分,可直接进行结果的计算。

复数部分与实数部分一样。

  1. 第二层蝶形计算

第二层蝶形有两种旋转因子分别为1和-i,蝶形上下部分间隔为2,可以使用vld4q_f32()将数据加载到float32x4x4_t的变量中,具体形式如下图:

第一行与第三行为同组蝶形的上下两部分(间隔为2),第二行与第四行为第二种蝶形的上下部分。对于旋转因子为1的部分,计算方式与第一层相同。对于第二种蝶形,旋转因子为-i,可以直接得到下半部分与蝶形因子的计算结果而无需乘法。

  1. 第三层及之后的

  1. 蝶形计算

第三层旋转因子有4个,蝶形上下部分间隔为4,可以选择使用vld1q_f32()加载数据到float32x4变量中,再加载之后的4个到第二个float32x4变量中。两个变量分别存储蝶形上下两部分的数据。然后进行常规的复数乘法运算与加减法。

后来发现这种方式的访存次数太多,考虑到armV8有32个向量寄存器,cache line大小为64B即16个float,利用vld1q_f32_x4()接口加载一个缓存行的数据,用4个向量寄存器存着,计算完再利用vst1q_f32_x4()存回去,将8次访存(4次取4次存)减少为2次访存(1次取1次存)。

实现了这个想法后,在飞腾CPU上利用g++编译发现不认识vld1q_f32_x4()与vst1q_f32_x4()接口!!

在我本机(macbook pro 2017)编码是可以看到<arm_neon.h>库中有这些接口的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值