【发布时间】: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