【发布时间】:2012-04-18 02:16:33
【问题描述】:
在数字滤波 C++ 应用程序中,我使用 std::inner_product(与 std::vector<double> 和 std::deque<double>)计算每个数据样本的滤波器系数和输入数据之间的点积。在分析我的应用程序后,我发现不少于 85% 的执行时间都花在了std::inner_product!
std::inner_product 优化到什么程度,例如在 GCC 中?
它是否使用 SIMD 指令?它是否执行循环展开?如何确保这一点?
基于此,是否值得实现自定义点积函数(尤其是在系数数量很少的情况下)? (但我想让函数尽可能通用)
更具体地说,这是我用来应用过滤器的一段代码:
std::deque<double> in(filterNum.size(), 0.0);
std::deque<double> out(filterDenom.size() - 1, 0.0);
const double gain = filterDenom.back();
for (unsigned int s = 0, size = data.size(); s < size; ++s) {
in.pop_front();
in.push_back(data[s] / gain);
data[s] = inner_product(in.begin(), in.end(), filterNum.begin(),
-inner_product(out.begin(), out.end(), filterDenom.begin(), 0.0));
out.pop_front();
out.push_back(data[s]);
}
通常,我使用二阶带通 IIR 滤波器,这意味着 filterNum 和 filterDenom(滤波器的分子和分母系数)的大小为 5。data 是包含输入样本的向量。
【问题讨论】:
-
您是否分析了调试版本?您希望在申请中花费更多时间吗?反正速度够快吗?
-
我确实使用 callgrind 对应用程序进行了概要分析,并使用 GCC 选项 -O1 -g。由于应用程序应用了数千个过滤器,我得到的结果并不奇怪。我已经使用 OpenMP 并行应用了多个过滤器(它工作得很好,我的 Xeon 2 x 6 核机器上的速度为 x24)。但是,任务仍然很艰巨,如果我能获得 2 倍的速度,超过 1 小时的执行时间,它远非微不足道!而且它不是只运行一次的应用程序类型...
-
直接用双数组写就行了;这将需要 10 分钟,您可以比较性能。我怀疑你会对 deque 和 inner_product 真正的“快速”程度感到震惊(但请确保你不旋转数组,尝试模拟 deque 在内部所做的事情)。
-
好的,现在我们都想看看纯版本的速度有多快。完成后在结果中添加评论。