gpt4 book ai didi

c++ - 数字滤波器和 std::inner_product 优化

转载 作者:太空宇宙 更新时间:2023-11-04 12:10:38 25 4
gpt4 key购买 nike

在数字滤波 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是包含输入样本的 vector 。

最佳答案

如果您直接编写代码,那么从中获得额外的 2 倍应该不难。部分原因可能是去除了 inner_product 的一些通用性,但也有一些原因是去除了 deques 的使用——如果你只保留一个指向输入数组的指针,你可以索引它并关闭过滤器数组内部循环,并在外部循环中递增指向输入数组的指针。

这些 inner_products 中的每一个都必须通过双端队列使用迭代器,

大部分(编码)工作随后变成了处理边缘条件。

然后去掉那个除法 - 它应该是乘以一个在循环外计算的常数。

内积本身非常高效(那里没什么可做的),但它需要在每次通过内循环时递增两个迭代器。没有明确的循环展开,但一个好的编译器可以展开一个如此简单的循环。并且编译器更有可能在遇到指令缓存问题之前知道将循环展开多远。

双端队列迭代器在纯指针上的效率几乎不如++。每个++至少有一个测试,并且可能有不止一个赋值。

这是一个简单的 (FIR) 滤波器的样子,不包括边缘条件的代码(在循环之外)

double norm = 1.0/sum;
double *p = data.values(); // start of input data
double *q = output.values(); // start of output buffer
int width = data.size() - filter.size();
for( int i = 0; i < width; ++i )
{
double *f = filter.values();
double accumulator = ( f[0] * p[0] );
for( int j = 1; j < filter.size(); ++j )
{
accumulator += ( f[i] * p[i] );
}
*q++ = accumulator * norm;
}

请注意,遗漏了一些杂乱的细节,这与您的过滤器不同,但它提供了思路。外循环内部的内容很容易适合现代指令缓存。内部循环可以由编译器展开。大多数现代架构都可以并行进行加法和乘法。

关于c++ - 数字滤波器和 std::inner_product 优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10009997/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com