提高 Vivado HLS 部门的性能

Improve performances of division Vivado HLS

我正在计算我的输入数据的增量平均值(这是一个包含 6 个元素的数组,所以我最终得到 6 个平均值)。

这是我每次有可用的新输入数组时使用的代码(显然我更新了样本数 ecc...):

computing_mean:for(int i=0;i<6;i++){
       temp_mean[i]=temp_mean[i] + (input[i]-temp_mean[i])/number_of_samples;
       //Possible optimization?
       //temp_mean[i]=temp_mean[i] + divide(input[i]-temp_mean[i],number_of_samples);

}

其中代码中的所有数据都是以下类型的数组或单个数字:

typedef ap_fixed <36,24,AP_RND_CONV,AP_SAT> decimalNumber;

根据我的综合报告,这个循环有 324 次延迟和 54 次迭代延迟,主要是由除法运算引起的。

有什么方法可以提高除法的速度吗?我尝试使用 hls_math 和除法函数,但它似乎不适用于我的数据类型。

编辑 1:我将我的性能分析器包含在 vivado HLS 中。稍后我将添加一个独立的可重现代码并进行另一次编辑。 如您所见,大部分时间都花在了 SDIV 上

除了三角函数,如 sin()FSIN = ~50-170 个周期)和 cos()FCOS = ~50-120 个周期)或其他东西就像sqrt()FSQRT = ~22个周期),除法永远是最痛苦的。

FDIV 是 15 个周期。 FADDFMUL 都是 5.

有些情况下您可以跳过除法而改为执行 bit-shifting,如果您正在处理整数数据并且除以的数字是 2 的幂,但仅此而已。

您可以在 tables like this 中查找任何给定指令的近似 CPU 周期成本。 FDIV 是一个昂贵的例子。

也就是说,您可以尝试的一件事是提前计算除法因子,然后使用乘法来应用它:

double inverse_n = 1 / number_of_samples;

temp_mean[i]=temp_mean[i] + (input[i]-temp_mean[i]) * inverse_n;

我不确定这是否可以节省很多,但如果您确实需要缩短周期,那么值得一试。