【问题标题】:Improve performances of division Vivado HLS提高 Vivado HLS 部门的性能
【发布时间】:2020-10-13 17:35:36
【问题描述】:

我正在计算输入数据的增量平均值(这是一个由 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

【问题讨论】:

  • ANSI C?这是一些遗留代码库吗?向量化只是利用 SIMD 指令,它不是 C 本身的函数。
  • 如果你问“有没有一根魔杖,我可以挥动这段代码并让它更快”,答案是否定的。如果您问“有没有办法通过重新编写代码来使代码更快”,答案很长而且很复杂,但是是的。困难但相对简单的方法是查看是否可以使用 SIMD 指令对其进行矢量化。更困难但可能更好的方法是查看是否可以将所有这些转储到 GPU 上并将其编写为内核函数。
  • 你要一根魔杖。它不存在。为什么你认为这条特定的线路是问题所在?你有分析报告吗?
  • 这可能看起来很长,但实际上并非如此。除法的计算成本更高,这是真的,但在大多数情况下它不会非常昂贵。如果您遇到性能问题,可能与以下之一有关:缓存未命中、数据布局问题、糟糕的结构设计或根本无效的算法。
  • 除了像sin()cos()这样的三角函数,或者像sqrt()这样的东西,除法永远是最痛苦的。在某些情况下,您可以跳过除法并进行位移,如果您正在处理整数数据并且您要除以的数字是 2 的幂,但仅此而已。

标签: c optimization vivado vivado-hls


【解决方案1】:

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

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

在某些情况下,您可以跳过除法并改为进行位移,如果您正在处理整数数据并且您要除以的数字是 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;

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

【讨论】:

    猜你喜欢
    • 2015-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-03
    • 1970-01-01
    • 1970-01-01
    • 2020-04-13
    相关资源
    最近更新 更多